primeiro commit
234
HealthOneProject/Lista-agendamento/agenda-consulta.html
Normal file
@ -0,0 +1,234 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="pt-BR">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>HealthOne • Agendar Consulta</title>
|
||||
<style>
|
||||
:root{
|
||||
--medicio-teal: #3fbbc0;
|
||||
--medicio-teal-600: #34a3a8;
|
||||
--medicio-dark: #2a2d34;
|
||||
--medicio-muted: #6b7280;
|
||||
--medicio-border: #e5e7eb;
|
||||
--medicio-white: #ffffff;
|
||||
--shadow: 0 8px 24px rgba(0,0,0,.06);
|
||||
--radius: 12px;
|
||||
}
|
||||
body{
|
||||
margin:0; font-family: Inter, sans-serif;
|
||||
background: var(--medicio-white); color: var(--medicio-dark);
|
||||
}
|
||||
.appbar{
|
||||
background:#ffffff; border-bottom:1px solid var(--medicio-border);
|
||||
padding:18px 20px; display:flex; align-items:center; gap:12px;
|
||||
}
|
||||
.logo {
|
||||
width: 80px;
|
||||
height: auto;
|
||||
border-radius: 50%; /* deixa redondo */
|
||||
box-shadow: 0 0 20px rgba(63, 187, 188, 0.7), 0 0 40px rgba(63, 187, 188, 0.4);
|
||||
}
|
||||
|
||||
main.wrap{
|
||||
max-width:600px; margin:24px auto; padding:0 20px 80px;
|
||||
}
|
||||
.btn{
|
||||
appearance:none; border:none; background: var(--medicio-teal); color:white;
|
||||
padding:10px 16px; border-radius:12px; cursor:pointer; font-weight:600;
|
||||
box-shadow:0 6px 16px rgba(63,187,192,.25); margin-right:8px;
|
||||
}
|
||||
.btn.secondary{ background:#ffffff; color:var(--medicio-dark); border:1px solid var(--medicio-border); box-shadow:none; }
|
||||
#consultaMarcada{ margin-bottom:20px; }
|
||||
ul{ padding-left:20px; margin-top:8px; }
|
||||
li{ margin-bottom:4px; }
|
||||
|
||||
/* Calendário */
|
||||
.calendar{ width:100%; border-collapse:collapse; margin-bottom:12px; }
|
||||
.calendar th, .calendar td{ width:14.28%; text-align:center; padding:6px; cursor:pointer; border-radius:6px; }
|
||||
.calendar th{ color:var(--medicio-muted); font-weight:500; }
|
||||
.calendar td:hover{ background: var(--medicio-teal-100); }
|
||||
.calendar .selected{ background: var(--medicio-teal); color:white; }
|
||||
.calendar-nav{ display:flex; justify-content:space-between; margin-bottom:8px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Topbar -->
|
||||
<div class="appbar">
|
||||
<img src="logo_HealthOne.jpeg" alt="HealthOne" class="logo">
|
||||
<div>
|
||||
|
||||
<small>Agendamento de Consulta</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<main class="wrap">
|
||||
<!-- Médico selecionado e consultas -->
|
||||
<div id="consultaMarcada"></div>
|
||||
|
||||
<!-- Calendário -->
|
||||
<div class="calendar-nav">
|
||||
<button id="prevMonth" class="btn secondary">◀</button>
|
||||
<div id="mesAno"></div>
|
||||
<button id="nextMonth" class="btn secondary">▶</button>
|
||||
</div>
|
||||
<table class="calendar" id="calendar">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Dom</th><th>Seg</th><th>Ter</th><th>Qua</th><th>Qui</th><th>Sex</th><th>Sáb</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Hora -->
|
||||
<div>
|
||||
<label for="horaConsulta">Escolha a hora:</label>
|
||||
|
||||
<select id="horaConsulta">
|
||||
<option value="07:00">07:00</option>
|
||||
<option value="07:30">07:00</option>
|
||||
<option value="08:00">08:00</option>
|
||||
<option value="08:30">08:30</option>
|
||||
<option value="09:00">09:00</option>
|
||||
<option value="09:30">09:30</option>
|
||||
<option value="10:00">10:00</option>
|
||||
<option value="10:30">10:30</option>
|
||||
<option value="11:00">11:00</option>
|
||||
<option value="11:30">11:30</option>
|
||||
<option value="12:00">12:00</option>
|
||||
<option value="12:30">12:30</option>
|
||||
<option value="13:00">13:00</option>
|
||||
<option value="13:30">13:30</option>
|
||||
<option value="14:00">14:00</option>
|
||||
<option value="14:30">14:30</option>
|
||||
<option value="15:00">15:00</option>
|
||||
<option value="15:30">15:30</option>
|
||||
<option value="16:00">16:00</option>
|
||||
<option value="16:30">16:30</option>
|
||||
<option value="17:00">17:00</option>
|
||||
<option value="17:30">17:30</option>
|
||||
<option value="18:00">18:00</option>
|
||||
<option value="18:30">18:30</option>
|
||||
<option value="19:00">19:00</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Botões -->
|
||||
<div>
|
||||
<button id="confirmarConsulta" class="btn">Confirmar Consulta</button>
|
||||
<button id="voltarLista" class="btn secondary">Voltar para Médicos</button>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
const medico = JSON.parse(localStorage.getItem('healthone_medico_escolhido'));
|
||||
const consultaDiv = document.getElementById('consultaMarcada');
|
||||
if(medico){
|
||||
consultaDiv.innerHTML = `<strong>Médico:</strong> ${medico.nome} (${medico.especialidade})`;
|
||||
}
|
||||
|
||||
document.getElementById('voltarLista').onclick = ()=>{
|
||||
window.location.href = 'index.html';
|
||||
};
|
||||
|
||||
let selectedDate = null;
|
||||
const calendarBody = document.querySelector('#calendar tbody');
|
||||
const mesAno = document.getElementById('mesAno');
|
||||
let currentMonth = new Date().getMonth();
|
||||
let currentYear = new Date().getFullYear();
|
||||
|
||||
function renderCalendar(month, year){
|
||||
calendarBody.innerHTML = '';
|
||||
const firstDay = new Date(year, month,1).getDay();
|
||||
const daysInMonth = new Date(year, month+1,0).getDate();
|
||||
mesAno.textContent = `${new Date(year, month).toLocaleString('pt-BR',{month:'long'})} ${year}`;
|
||||
let row = document.createElement('tr');
|
||||
for(let i=0;i<firstDay;i++){ row.appendChild(document.createElement('td')); }
|
||||
for(let d=1; d<=daysInMonth; d++){
|
||||
if(row.children.length===7){ calendarBody.appendChild(row); row=document.createElement('tr'); }
|
||||
const td = document.createElement('td');
|
||||
td.textContent = d;
|
||||
td.onclick = ()=>{
|
||||
selectedDate = new Date(year, month, d);
|
||||
document.querySelectorAll('#calendar td').forEach(cell=>cell.classList.remove('selected'));
|
||||
td.classList.add('selected');
|
||||
|
||||
// 🔥 verificar horários ocupados neste dia
|
||||
marcarHorariosOcupados();
|
||||
};
|
||||
row.appendChild(td);
|
||||
}
|
||||
while(row.children.length<7){ row.appendChild(document.createElement('td')); }
|
||||
calendarBody.appendChild(row);
|
||||
}
|
||||
|
||||
document.getElementById('prevMonth').onclick = ()=>{
|
||||
currentMonth--;
|
||||
if(currentMonth<0){ currentMonth=11; currentYear--; }
|
||||
renderCalendar(currentMonth,currentYear);
|
||||
};
|
||||
document.getElementById('nextMonth').onclick = ()=>{
|
||||
currentMonth++;
|
||||
if(currentMonth>11){ currentMonth=0; currentYear++; }
|
||||
renderCalendar(currentMonth,currentYear);
|
||||
};
|
||||
|
||||
renderCalendar(currentMonth,currentYear);
|
||||
|
||||
function marcarHorariosOcupados(){
|
||||
if (!selectedDate) return;
|
||||
const dataStr = selectedDate.toISOString().slice(0,10);
|
||||
const consultas = JSON.parse(localStorage.getItem('healthone_consultas') || '[]');
|
||||
|
||||
// pega horários já usados neste dia para este médico
|
||||
const ocupados = consultas
|
||||
.filter(c => c.medicoId === medico.id && c.dataHora.startsWith(dataStr))
|
||||
.map(c => c.dataHora.split(' ')[1]);
|
||||
|
||||
const horaInput = document.getElementById('horaConsulta');
|
||||
|
||||
// se o input estiver num horário ocupado, limpa e avisa
|
||||
if (ocupados.includes(horaInput.value)) {
|
||||
horaInput.value = '';
|
||||
alert('Alguns horários deste dia já estão ocupados. Escolha outro.');
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('confirmarConsulta').onclick = ()=>{
|
||||
const hora = document.getElementById('horaConsulta').value;
|
||||
if(!selectedDate || !hora){ alert('Escolha data e hora'); return; }
|
||||
const dataStr = selectedDate.toISOString().slice(0,10);
|
||||
const novaConsulta = {
|
||||
medicoId: medico.id,
|
||||
medicoNome: medico.nome,
|
||||
especialidade: medico.especialidade,
|
||||
dataHora: `${dataStr} ${hora}`
|
||||
};
|
||||
let consultas = JSON.parse(localStorage.getItem('healthone_consultas') || '[]');
|
||||
|
||||
// verificar se já existe consulta para o mesmo médico, data e hora
|
||||
const ocupado = consultas.some(c =>
|
||||
c.medicoId === medico.id && c.dataHora === `${dataStr} ${hora}`
|
||||
);
|
||||
|
||||
if (ocupado) {
|
||||
alert('Esse horário já está ocupado para este médico!');
|
||||
return;
|
||||
}
|
||||
|
||||
consultas.push(novaConsulta);
|
||||
localStorage.setItem('healthone_consultas', JSON.stringify(consultas));
|
||||
alert('Consulta marcada com sucesso!');
|
||||
renderConsultas();
|
||||
};
|
||||
|
||||
function renderConsultas(){
|
||||
// Mantém apenas o nome do médico e sua especialidade
|
||||
consultaDiv.innerHTML = `<strong>Médico:</strong> ${medico.nome} (${medico.especialidade})`;
|
||||
}
|
||||
|
||||
renderConsultas();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
668
HealthOneProject/Lista-agendamento/agendamento.html
Normal file
@ -0,0 +1,668 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="pt-BR">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>HealthOne • Médicos (CRUD)</title>
|
||||
<style>
|
||||
:root{
|
||||
/* Paleta HealthOne (ajuste se quiser) */
|
||||
--brand-primary:#2563eb;
|
||||
--brand-primary-600:#1d4ed8;
|
||||
--brand-accent:#22c55e;
|
||||
--brand-surface:#0b1220;
|
||||
--text:#e5e7eb;
|
||||
--muted:#94a3b8;
|
||||
--danger:#ef4444;
|
||||
--warning:#f59e0b;
|
||||
--bg:#0f172a;
|
||||
--card:#111827;
|
||||
--card-2:#0f172a;
|
||||
--border:#1f2937;
|
||||
--ring:#3b82f6;
|
||||
--shadow: 0 10px 30px rgba(0,0,0,.35);
|
||||
--radius: 16px;
|
||||
}
|
||||
|
||||
*{box-sizing:border-box}
|
||||
html,body{height:100%}
|
||||
body{
|
||||
margin:0;
|
||||
background: radial-gradient(1200px 600px at 20% -10%, rgba(59,130,246,.15), transparent 60%),
|
||||
radial-gradient(1200px 700px at 120% 20%, rgba(34,197,94,.10), transparent 55%),
|
||||
var(--bg);
|
||||
color:var(--text);
|
||||
font-family: Inter, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji";
|
||||
line-height:1.35;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
.appbar{
|
||||
position:sticky; top:0; z-index:10;
|
||||
backdrop-filter: saturate(120%) blur(8px);
|
||||
background: rgba(15,23,42,.6);
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.appbar-inner{
|
||||
max-width:1200px; margin:0 auto; padding:14px 20px;
|
||||
display:flex; align-items:center; gap:16px; justify-content:space-between;
|
||||
}
|
||||
.brand{
|
||||
display:flex; align-items:center; gap:12px;
|
||||
}
|
||||
.logo{
|
||||
width:36px; height:36px; border-radius:10px;
|
||||
background: linear-gradient(135deg, var(--brand-primary), var(--brand-accent));
|
||||
box-shadow: 0 8px 20px rgba(37,99,235,.45), inset 0 0 10px rgba(255,255,255,.15);
|
||||
}
|
||||
.brand h1{
|
||||
font-size:18px; margin:0; letter-spacing:.4px; font-weight:700;
|
||||
}
|
||||
.brand small{color:var(--muted); display:block; margin-top:2px; font-weight:500}
|
||||
|
||||
.wrap{
|
||||
max-width:1200px; margin:24px auto; padding:0 20px 80px;
|
||||
}
|
||||
|
||||
/* Top actions / filtros */
|
||||
.toolbar{
|
||||
display:grid; grid-template-columns: 1fr 220px 180px 160px auto;
|
||||
gap:12px; margin:16px 0 12px;
|
||||
}
|
||||
@media (max-width: 980px){
|
||||
.toolbar{ grid-template-columns: 1fr 1fr; }
|
||||
}
|
||||
.field{
|
||||
display:flex; align-items:center; gap:10px; background: var(--card); border:1px solid var(--border);
|
||||
padding:10px 12px; border-radius: 12px;
|
||||
}
|
||||
.field input,.field select{
|
||||
width:100%; background:transparent; border:0; color:var(--text); outline:none; font-size:14px;
|
||||
}
|
||||
.btn{
|
||||
appearance:none; border:1px solid var(--brand-primary);
|
||||
background: linear-gradient(180deg, var(--brand-primary), var(--brand-primary-600));
|
||||
color:white; padding:10px 14px; border-radius:12px; font-weight:600; cursor:pointer;
|
||||
box-shadow: 0 8px 20px rgba(37,99,235,.35);
|
||||
transition: transform .04s ease, filter .2s ease;
|
||||
white-space:nowrap;
|
||||
}
|
||||
|
||||
.btn.secondary{
|
||||
background: transparent; border-color:var(--border); color:var(--text);
|
||||
box-shadow:none;
|
||||
}
|
||||
.switch{
|
||||
display:flex; align-items:center; gap:10px; padding:10px 12px; border-radius:12px;
|
||||
border:1px solid var(--border); background:var(--card);
|
||||
}
|
||||
.switch input{ accent-color: var(--brand-primary); width:18px; height:18px; }
|
||||
|
||||
/* Card */
|
||||
.card{
|
||||
background: linear-gradient(180deg, rgba(255,255,255,.02), transparent 18%) , var(--card-2);
|
||||
border:1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow);
|
||||
}
|
||||
.card-header{
|
||||
display:flex; align-items:center; justify-content:space-between; padding:16px 16px 8px 16px;
|
||||
border-bottom:1px solid var(--border);
|
||||
}
|
||||
.card-header h2{margin:0; font-size:18px}
|
||||
.card-content{ padding: 8px 16px 16px 16px; }
|
||||
|
||||
/* Tabela */
|
||||
.table{
|
||||
width:100%; border-collapse:separate; border-spacing:0 8px;
|
||||
}
|
||||
.thead{ color:var(--muted); font-size:12px; text-transform:uppercase; letter-spacing:.6px; }
|
||||
.thead th{ text-align:left; padding:0 12px 8px; }
|
||||
.row{
|
||||
background: var(--card); border:1px solid var(--border);
|
||||
border-radius:12px; overflow:hidden;
|
||||
}
|
||||
.row td{
|
||||
padding:12px; border-bottom:1px solid rgba(255,255,255,.04);
|
||||
}
|
||||
.row td:last-child{ border-bottom:0; }
|
||||
.badge{
|
||||
font-size:12px; padding:4px 8px; border-radius:999px; border:1px solid var(--border);
|
||||
background: rgba(59,130,246,.12);
|
||||
white-space: nowrap; /* Isso impede a quebra de linha dentro do badge */
|
||||
}
|
||||
.convenios {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
.badge.ok{ background: rgba(34,197,94,.12); border-color: rgba(34,197,94,.4); color:#bbf7d0; }
|
||||
.badge.warn{ background: rgba(245,158,11,.12); border-color: rgba(245,158,11,.4); color:#fde68a; }
|
||||
|
||||
.actions{
|
||||
display:flex; gap:8px; flex-wrap:wrap;
|
||||
}
|
||||
.btn.icon{
|
||||
padding:8px 10px; font-size:13px; border-radius:10px;
|
||||
}
|
||||
.btn.danger{
|
||||
background: linear-gradient(180deg, #ef4444, #b91c1c);
|
||||
border-color:#b91c1c; box-shadow: 0 8px 20px rgba(239,68,68,.25);
|
||||
}
|
||||
.btn.outline{
|
||||
background: transparent; color: var(--text);
|
||||
border-color: var(--border); box-shadow:none;
|
||||
}
|
||||
|
||||
/* Paginação */
|
||||
.pagination{
|
||||
display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:16px;
|
||||
}
|
||||
.pagination .pages{
|
||||
display:flex; gap:8px; align-items:center; flex-wrap:wrap;
|
||||
}
|
||||
.page{
|
||||
border:1px solid var(--border); background:var(--card); color:var(--text);
|
||||
padding:8px 10px; border-radius:10px; cursor:pointer;
|
||||
}
|
||||
.page.active{ border-color: var(--brand-primary); outline:2px solid rgba(37,99,235,.35); }
|
||||
|
||||
/* Modal (mantive CSS, mas o HTML foi removido) */
|
||||
.modal-backdrop{ display:none; }
|
||||
|
||||
.empty{
|
||||
text-align:center; color:var(--muted); padding:28px 12px;
|
||||
}
|
||||
|
||||
/* Click sortable */
|
||||
th.sortable{ cursor:pointer; user-select:none; }
|
||||
th.sortable::after{
|
||||
content:'↕'; margin-left:6px; opacity:.4; font-size:11px;
|
||||
}
|
||||
|
||||
/* ===========================
|
||||
THEME: Medicio-like
|
||||
=========================== */
|
||||
:root{
|
||||
--medicio-teal: #3fbbc0;
|
||||
--medicio-teal-600: #34a3a8;
|
||||
--medicio-teal-100: #e5f7f8;
|
||||
--medicio-dark: #2a2d34;
|
||||
--medicio-muted: #6b7280;
|
||||
--medicio-border: #e5e7eb;
|
||||
--medicio-white: #ffffff;
|
||||
}
|
||||
:root{
|
||||
--brand-primary: var(--medicio-teal);
|
||||
--brand-primary-600: var(--medicio-teal-600);
|
||||
--brand-accent: var(--medicio-teal);
|
||||
--bg: var(--medicio-white);
|
||||
--card: #ffffff;
|
||||
--card-2: #ffffff;
|
||||
--text: var(--medicio-dark);
|
||||
--muted: var(--medicio-muted);
|
||||
--border: var(--medicio-border);
|
||||
--ring: var(--medicio-teal);
|
||||
--shadow: 0 8px 24px rgba(0,0,0,.06);
|
||||
--radius: 12px;
|
||||
}
|
||||
body{
|
||||
background: var(--medicio-white) !important;
|
||||
color: var(--medicio-dark) !important;
|
||||
}
|
||||
.topstrip-medicio{
|
||||
background: var(--medicio-teal);
|
||||
color: #eaffff;
|
||||
font: 500 13px/1.2 Inter, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial;
|
||||
padding: 8px 20px;
|
||||
display:flex; align-items:center; gap:10px;
|
||||
}
|
||||
.topstrip-medicio .ico{ opacity:.9 }
|
||||
.appbar{
|
||||
background: #ffffff !important;
|
||||
backdrop-filter: none !important;
|
||||
border-bottom: 1px solid var(--medicio-border) !important;
|
||||
}
|
||||
.appbar-inner{
|
||||
padding: 18px 20px !important;
|
||||
}
|
||||
.brand h1{
|
||||
color: var(--medicio-dark) !important;
|
||||
letter-spacing:.2px;
|
||||
}
|
||||
.brand small{
|
||||
color: var(--medicio-muted) !important;
|
||||
}
|
||||
.logo{
|
||||
width:90px;
|
||||
height:auto;
|
||||
}
|
||||
.toolbar{
|
||||
gap: 14px !important;
|
||||
margin: 24px 0 12px !important;
|
||||
}
|
||||
.field,
|
||||
.switch{
|
||||
background: #ffffff !important;
|
||||
border: 1px solid var(--medicio-border) !important;
|
||||
padding: 12px 14px !important;
|
||||
border-radius: 10px !important;
|
||||
}
|
||||
.field input, .field select{
|
||||
color: var(--medicio-dark) !important;
|
||||
}
|
||||
.btn{
|
||||
background: var(--medicio-teal) !important;
|
||||
border-color: var(--medicio-teal) !important;
|
||||
box-shadow: 0 6px 16px rgba(63,187,192,.25) !important;
|
||||
}
|
||||
.btn:hover{ filter: brightness(.98); }
|
||||
.btn:active{ transform: translateY(1px); }
|
||||
.btn.secondary{
|
||||
background: #ffffff !important;
|
||||
color: var(--medicio-dark) !important;
|
||||
border-color: var(--medicio-border) !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
.btn.outline{
|
||||
background: #ffffff !important;
|
||||
border-color: var(--medicio-border) !important;
|
||||
}
|
||||
.btn.danger{
|
||||
background: linear-gradient(180deg, #ef4444, #d01e1e) !important;
|
||||
border-color:#d01e1e !important;
|
||||
box-shadow: 0 6px 16px rgba(239,68,68,.18) !important;
|
||||
}
|
||||
.card{
|
||||
background: #ffffff !important;
|
||||
border: 1px solid var(--medicio-border) !important;
|
||||
border-radius: 12px !important;
|
||||
box-shadow: var(--shadow) !important;
|
||||
}
|
||||
.card-header{
|
||||
padding: 16px 18px 10px 18px !important;
|
||||
}
|
||||
.card-content{ padding: 8px 18px 18px 18px !important; }
|
||||
.table{ border-spacing: 0 10px !important; }
|
||||
.row{
|
||||
background:#ffffff !important;
|
||||
border:1px solid var(--medicio-border) !important;
|
||||
border-radius:10px !important;
|
||||
}
|
||||
.row td{ border-bottom: 0 !important; }
|
||||
.thead{ color: var(--medicio-muted) !important; }
|
||||
.badge{
|
||||
background: var(--medicio-teal-100) !important;
|
||||
color: #20767a !important;
|
||||
border: 1px solid #c8eef0 !important;
|
||||
}
|
||||
.badge.ok{
|
||||
background: #e7f7ea !important;
|
||||
color: #217a31 !important;
|
||||
border-color:#cfeedd !important;
|
||||
}
|
||||
.badge.warn{
|
||||
background: #fff6e6 !important;
|
||||
color: #8a5b07 !important;
|
||||
border-color: #fde8c3 !important;
|
||||
}
|
||||
.page{
|
||||
background:#ffffff !important;
|
||||
color: var(--medicio-dark) !important;
|
||||
border:1px solid var(--medicio-border) !important;
|
||||
border-radius: 999px !important;
|
||||
padding: 8px 12px !important;
|
||||
}
|
||||
.page.active{
|
||||
border-color: var(--medicio-teal) !important;
|
||||
outline: 2px solid rgba(63,187,192,.18) !important;
|
||||
}
|
||||
.modal{ background:#ffffff !important; border:1px solid var(--medicio-border) !important; }
|
||||
.modal header, .modal footer{ border-color: var(--medicio-border) !important; }
|
||||
.input{
|
||||
background:#ffffff !important; border:1px solid var(--medicio-border) !important;
|
||||
border-radius:10px !important; padding: 12px 14px !important;
|
||||
}
|
||||
.input label{ color: var(--medicio-muted) !important; }
|
||||
.input input, .input select, .input textarea{ color: var(--medicio-dark) !important; }
|
||||
th.sortable::after{ opacity:.35 !important; }
|
||||
.topnav{
|
||||
position:sticky; top:0; z-index:10; background:var(--bg);
|
||||
border-bottom:1px solid var(--line); padding:12px 24px;
|
||||
display:flex; align-items:center; gap:22px;
|
||||
}
|
||||
.logo{display:flex; align-items:center; gap:10px; margin-right:8px}
|
||||
.logo-badge{width:36px;height:36px;border-radius:12px;
|
||||
background:linear-gradient(135deg,var(--brand),#64e4dc);
|
||||
display:grid;place-items:center;color:#fff;font-weight:800;box-shadow:var(--soft)}
|
||||
.logo span{font-weight:800;color:var(--brand-600);letter-spacing:.3px}
|
||||
|
||||
.tabs{display:flex; gap:16px; align-items:center; margin-left:600px}
|
||||
.tabs a{color:var(--muted); text-decoration:none; font-weight:600}
|
||||
.tabs a:hover{color:var(--brand-600, )}
|
||||
.tabs .ativo{background:var(--bran, #64e4dc); color:#f8f8f8; padding:8px 18px;
|
||||
border-radius:999px; box-shadow:0 4px 10px rgba(0, 211, 248, 0.25)}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Topbar -->
|
||||
|
||||
<div class="appbar">
|
||||
<div class="appbar-inner">
|
||||
<div class="brand">
|
||||
<img src="logo_HealthOne.jpeg" alt="HealthOne" class="logo">
|
||||
</div>
|
||||
<div>
|
||||
<small>Diretório de Médicos • CRUD</small>
|
||||
</div>
|
||||
<!-- ===== NAV SUPERIOR ===== -->
|
||||
<!-- você pode colocar um campo de busca aqui se quiser -->
|
||||
<nav class="tabs">
|
||||
<a href="dash-pacientes.html" >Início</a>
|
||||
<a href="agendamento.html" class="ativo">Marcar Consulta</a>
|
||||
</nav>
|
||||
</div>
|
||||
<!-- Botão de novo médico removido -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<main class="wrap">
|
||||
<!-- Filtros -->
|
||||
<div class="toolbar">
|
||||
<div class="field" title="Pesquise por nome, CRM, cidade, especialidade">
|
||||
<span>🔎</span>
|
||||
<input id="searchInput" type="search" placeholder="Pesquisar (ex.: Neurologista, Ginecologista, Dr. Ana, CRM...)" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<select id="especialidadeFilter">
|
||||
<option value="">Todas as especialidades</option>
|
||||
<option>Cardiologista</option>
|
||||
<option>Clínico Geral</option>
|
||||
<option>Dermatologista</option>
|
||||
<option>Endocrinologista</option>
|
||||
<option>Ginecologista</option>
|
||||
<option>Neurologista</option>
|
||||
<option>Oftalmologista</option>
|
||||
<option>Ortopedista</option>
|
||||
<option>Pediatra</option>
|
||||
<option>Psiquiatra</option>
|
||||
<option>Urologista</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="switch">
|
||||
<input id="disponiveisToggle" type="checkbox" />
|
||||
<label for="disponiveisToggle">Somente disponíveis</label>
|
||||
</div>
|
||||
<button id="limparFiltros" class="btn secondary">Limpar filtros</button>
|
||||
</div>
|
||||
|
||||
<!-- Tabela -->
|
||||
<section class="card" aria-label="Lista de médicos">
|
||||
<div class="card-header">
|
||||
<h2>Médicos</h2>
|
||||
<div class="muted" style="color:var(--muted); font-size:13px">Clique no título das colunas para ordenar</div>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<table class="table" aria-describedby="Lista de médicos">
|
||||
<thead class="thead">
|
||||
<tr>
|
||||
<th class="sortable" data-sort="nome">Médico</th>
|
||||
<th class="sortable" data-sort="especialidade">Especialidade</th>
|
||||
<th class="sortable" data-sort="cidade">Cidade</th>
|
||||
<th>Contato</th>
|
||||
<th>Atende por</th>
|
||||
<th class="sortable" data-sort="preco">Consulta</th>
|
||||
<th class="sortable" data-sort="proxDisponivel">Próxima janela</th>
|
||||
<th class="sortable" data-sort="disponivel">Status</th>
|
||||
<th style="text-align:right">Ações</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tbody"></tbody>
|
||||
</table>
|
||||
|
||||
<div id="emptyState" class="empty" hidden>
|
||||
Nenhum médico encontrado. Ajuste os filtros ou cadastre um novo.
|
||||
</div>
|
||||
|
||||
<div class="pagination">
|
||||
<div class="pages" id="pages"></div>
|
||||
<div style="display:flex; align-items:center; gap:8px">
|
||||
<button id="prevPage" class="page">◀</button>
|
||||
<button id="nextPage" class="page">▶</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<!-- Modal Add/Edit REMOVIDO -->
|
||||
|
||||
<script>
|
||||
// ---------- Util ----------
|
||||
const $ = (sel, root = document) => root.querySelector(sel);
|
||||
const $$ = (sel, root = document) => Array.from(root.querySelectorAll(sel));
|
||||
const fmtMoney = v => (v == null || v === '') ? '-' : `R$ ${Number(v).toFixed(2).replace('.',',')}`;
|
||||
const fmtDateTime = iso => {
|
||||
if(!iso) return '-';
|
||||
try{
|
||||
const d = new Date(iso);
|
||||
if(isNaN(d)) return '-';
|
||||
return d.toLocaleString('pt-BR', { dateStyle:'short', timeStyle:'short' });
|
||||
}catch{return '-'}
|
||||
};
|
||||
const debounce = (fn, ms=250)=>{ let t; return (...a)=>{ clearTimeout(t); t=setTimeout(()=>fn(...a), ms); }};
|
||||
|
||||
// ---------- Estado ----------
|
||||
const STORAGE_KEY = 'healthone_medicos';
|
||||
let medicos = [];
|
||||
let page = 1;
|
||||
const PAGE_SIZE = 10;
|
||||
let sortBy = 'nome';
|
||||
let sortDir = 'asc';
|
||||
|
||||
function loadSeedIfEmpty(){
|
||||
const seed = [
|
||||
{id:crypto.randomUUID(), nome:'Dra. Ana Clara Silva', especialidade:'Ginecologista', crm:'CRM 12345-AL', telefone:'(82) 98888-1111', email:'ana.silva@healthone.com', cidade:'Maceió/AL', preco:250, proxDisponivel: future(1), disponivel:true, atendePor:'Convênio X, Convênio Y'},
|
||||
{id:crypto.randomUUID(), nome:'Dr. Bruno Mendes', especialidade:'Neurologista', crm:'CRM 98765-AL', telefone:'(82) 97777-2222', email:'bruno.mendes@healthone.com', cidade:'Maceió/AL', preco:300, proxDisponivel: future(2), disponivel:true, atendePor:'Particular, Convênio Z'},
|
||||
{id:crypto.randomUUID(), nome:'Dra. Camila Rocha', especialidade:'Dermatologista', crm:'CRM 11223-AL', telefone:'(82) 96666-3333', email:'camila.rocha@healthone.com', cidade:'Rio Largo/AL', preco:220, proxDisponivel: future(5), disponivel:false, atendePor:'Somente particular'},
|
||||
{id:crypto.randomUUID(), nome:'Dr. Daniel Souza', especialidade:'Cardiologista', crm:'CRM 33445-AL', telefone:'(82) 95555-4444', email:'daniel.souza@healthone.com', cidade:'Marechal/AL', preco:280, proxDisponivel: future(3), disponivel:true, atendePor:'Convênio W, Particular'},
|
||||
{id:crypto.randomUUID(), nome:'Dra. Elisa Nunes', especialidade:'Clínico Geral', crm:'CRM 55667-AL', telefone:'(82) 94444-5555', email:'elisa.nunes@healthone.com', cidade:'Maceió/AL', preco:180, proxDisponivel: future(1), disponivel:true, atendePor:'SUS, Convênio X, Convênio Z'},
|
||||
{id:crypto.randomUUID(), nome:'Dr. Felipe Barros', especialidade:'Ortopedista', crm:'CRM 77889-AL', telefone:'(82) 93333-6666', email:'felipe.barros@healthone.com', cidade:'Maceió/AL', preco:260, proxDisponivel: future(7), disponivel:false, atendePor:'Particular, Convênio W'},
|
||||
{id:crypto.randomUUID(), nome:'Dra. Gabriela Lima', especialidade:'Pediatra', crm:'CRM 99887-AL', telefone:'(82) 92222-7777', email:'gabriela.lima@healthone.com', cidade:'Maceió/AL', preco:200, proxDisponivel: future(4), disponivel:true, atendePor:'Convênio X, Particular'},
|
||||
{id:crypto.randomUUID(), nome:'Dr. Henrique Castro', especialidade:'Psiquiatra', crm:'CRM 66554-AL', telefone:'(82) 91111-8888', email:'henrique.castro@healthone.com', cidade:'Maceió/AL', preco:320, proxDisponivel: future(6), disponivel:true, atendePor:'Convênio X, Convênio Y'}
|
||||
];
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(seed));
|
||||
return seed;
|
||||
}
|
||||
function future(days){
|
||||
const d = new Date(); d.setDate(d.getDate()+days); d.setHours(9,0,0,0);
|
||||
const iso = new Date(d.getTime() - d.getTimezoneOffset()*60000).toISOString().slice(0,16);
|
||||
return iso;
|
||||
}
|
||||
|
||||
function load(){
|
||||
const raw = localStorage.getItem(STORAGE_KEY);
|
||||
medicos = raw ? JSON.parse(raw) : loadSeedIfEmpty();
|
||||
|
||||
// 🔹 Garante que todos os médicos tenham "atendePor" sem sobrescrever os existentes
|
||||
medicos = medicos.map(m => {
|
||||
if(!('atendePor' in m) || !m.atendePor) {
|
||||
return { ...m, atendePor: 'Particular' };
|
||||
}
|
||||
return m;
|
||||
});
|
||||
|
||||
// salva de volta atualizado
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(medicos));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ---------- Filtros ----------
|
||||
const searchInput = $('#searchInput');
|
||||
const especialidadeFilter = $('#especialidadeFilter');
|
||||
const disponiveisToggle = $('#disponiveisToggle');
|
||||
|
||||
function getFilters(){
|
||||
return {
|
||||
q: (searchInput.value || '').trim().toLowerCase(),
|
||||
esp: especialidadeFilter.value,
|
||||
onlyAvail: disponiveisToggle.checked
|
||||
};
|
||||
}
|
||||
|
||||
function applyFilters(list){
|
||||
const {q, esp, onlyAvail} = getFilters();
|
||||
return list.filter(m=>{
|
||||
if(esp && m.especialidade !== esp) return false;
|
||||
if(onlyAvail && !m.disponivel) return false;
|
||||
if(!q) return true;
|
||||
const hay = `${m.nome} ${m.especialidade} ${m.cidade} ${m.crm}`.toLowerCase();
|
||||
return hay.includes(q);
|
||||
});
|
||||
}
|
||||
|
||||
// ---------- Ordenação ----------
|
||||
function sortList(list){
|
||||
const dir = sortDir === 'asc' ? 1 : -1;
|
||||
return [...list].sort((a,b)=>{
|
||||
let va = a[sortBy], vb = b[sortBy];
|
||||
if(sortBy === 'preco'){ va = Number(va||0); vb = Number(vb||0); }
|
||||
if(sortBy === 'proxDisponivel'){
|
||||
va = va ? new Date(va).getTime() : 0;
|
||||
vb = vb ? new Date(vb).getTime() : 0;
|
||||
}
|
||||
if(typeof va === 'string') va = va.toLowerCase();
|
||||
if(typeof vb === 'string') vb = vb.toLowerCase();
|
||||
if(va < vb) return -1*dir;
|
||||
if(va > vb) return 1*dir;
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
// ---------- Paginação ----------
|
||||
function paginate(list){
|
||||
const total = Math.max(1, Math.ceil(list.length / PAGE_SIZE));
|
||||
if(page > total) page = total;
|
||||
const start = (page-1)*PAGE_SIZE;
|
||||
const end = start + PAGE_SIZE;
|
||||
return { totalPages: total, items: list.slice(start, end) };
|
||||
}
|
||||
function renderPages(total){
|
||||
const pages = $('#pages'); pages.innerHTML = '';
|
||||
for(let i=1;i<=total;i++){
|
||||
const b = document.createElement('button');
|
||||
b.className = 'page' + (i===page ? ' active':'');
|
||||
b.textContent = i;
|
||||
b.addEventListener('click', ()=>{ page=i; render(); });
|
||||
pages.appendChild(b);
|
||||
}
|
||||
$('#prevPage').onclick = ()=>{ if(page>1){ page--; render(); } };
|
||||
$('#nextPage').onclick = ()=>{ if(page<total){ page++; render(); } };
|
||||
}
|
||||
|
||||
// ---------- Render ----------
|
||||
function render(){
|
||||
const tbody = $('#tbody');
|
||||
const empty = $('#emptyState');
|
||||
let data = applyFilters(medicos);
|
||||
data = sortList(data);
|
||||
const { totalPages, items } = paginate(data);
|
||||
|
||||
tbody.innerHTML = '';
|
||||
if(items.length === 0){
|
||||
empty.hidden = false;
|
||||
}else{
|
||||
empty.hidden = true;
|
||||
for(const m of items){
|
||||
const tr = document.createElement('tr'); tr.className='row';
|
||||
tr.innerHTML = `
|
||||
<td>
|
||||
<div style="display:flex; align-items:center; gap:10px;">
|
||||
<div style="width:36px; height:36px; border-radius:10px; background:linear-gradient(135deg, var(--brand-primary), var(--brand-accent));"></div>
|
||||
<div>
|
||||
<div style="font-weight:600">${escapeHTML(m.nome)}</div>
|
||||
<div style="color:var(--muted); font-size:12px">${escapeHTML(m.crm||'-')}</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td><span class="badge">${escapeHTML(m.especialidade)}</span></td>
|
||||
<td>${escapeHTML(m.cidade||'-')}</td>
|
||||
<td>
|
||||
<div style="font-size:13px; color:var(--muted)">
|
||||
${escapeHTML(m.telefone||'-')} • ${escapeHTML(m.email||'-')}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="convenios">
|
||||
${(m.atendePor || '-').split(',').map(c => `<span class="badge">${escapeHTML(c.trim())}</span>`).join('')}
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td>${fmtMoney(m.preco)}</td>
|
||||
<td>${fmtDateTime(m.proxDisponivel)}</td>
|
||||
<td>
|
||||
${m.disponivel ? '<span class="badge ok">Disponível</span>' : '<span class="badge warn">Indisponível</span>'}
|
||||
</td>
|
||||
<td style="text-align:right">
|
||||
<div class="actions">
|
||||
<button class="btn icon outline" title="Escolher / Marcar" data-act="marcar" data-id="${m.id}">Marcar</button>
|
||||
</div>
|
||||
</td>
|
||||
`;
|
||||
tbody.appendChild(tr);
|
||||
}
|
||||
}
|
||||
renderPages(totalPages);
|
||||
|
||||
// Actions
|
||||
$$('#tbody [data-act]').forEach(btn=>{
|
||||
const id = btn.getAttribute('data-id');
|
||||
const act = btn.getAttribute('data-act');
|
||||
btn.onclick = ()=> onAction(act, id);
|
||||
});
|
||||
}
|
||||
|
||||
function escapeHTML(s){
|
||||
if(s==null) return '';
|
||||
return String(s).replace(/[&<>"']/g, m => ({'&':'&','<':'<','>':'>','"':'"', "'":'''}[m]));
|
||||
}
|
||||
|
||||
function onAction(act, id){
|
||||
const idx = medicos.findIndex(m=>m.id===id);
|
||||
if(idx===-1) return;
|
||||
const m = medicos[idx];
|
||||
if(act==='marcar'){
|
||||
localStorage.setItem('healthone_medico_escolhido', JSON.stringify(m));
|
||||
window.location.href = 'agenda-consulta.html'; // redireciona para agenda
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---------- Ordenação por cabeçalho ----------
|
||||
$$('.thead th.sortable').forEach(th=>{
|
||||
th.addEventListener('click', ()=>{
|
||||
const key = th.getAttribute('data-sort');
|
||||
if(sortBy === key){ sortDir = (sortDir === 'asc' ? 'desc' : 'asc'); }
|
||||
else{ sortBy = key; sortDir = 'asc'; }
|
||||
render();
|
||||
});
|
||||
});
|
||||
|
||||
// ---------- Filtros listeners ----------
|
||||
searchInput.addEventListener('input', debounce(()=>{
|
||||
page=1; render();
|
||||
}, 250));
|
||||
especialidadeFilter.addEventListener('change', ()=>{ page=1; render(); });
|
||||
disponiveisToggle.addEventListener('change', ()=>{ page=1; render(); });
|
||||
$('#limparFiltros').onclick = ()=>{
|
||||
searchInput.value = '';
|
||||
especialidadeFilter.value = '';
|
||||
disponiveisToggle.checked = false;
|
||||
page = 1; render();
|
||||
};
|
||||
|
||||
// ---------- Init ----------
|
||||
load();
|
||||
render();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
263
HealthOneProject/Lista-agendamento/dash-pacientes.html
Normal file
@ -0,0 +1,263 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="pt-br">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>HealthOne — Dashboard do Paciente</title>
|
||||
<style>
|
||||
/* ====== TOKENS ====== */
|
||||
:root{
|
||||
--brand:#1db7ae; --brand-600:#12968f; --brand-100:#e7f7f6;
|
||||
--ink:#24323f; --muted:#6b7a88; --line:#e6eaef;
|
||||
--bg:#ffffff; --app:#f4f7fb; --radius:18px;
|
||||
--shadow:0 12px 28px rgba(18,150,143,.12);
|
||||
--soft:0 6px 18px rgba(36,50,63,.08);
|
||||
}
|
||||
*{box-sizing:border-box}
|
||||
body{margin:0;background:var(--app);color:var(--ink);
|
||||
font:14px/1.45 "Inter",system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif}
|
||||
|
||||
/* ====== TOP NAV ====== */
|
||||
.topnav{
|
||||
position:sticky; top:0; z-index:10; background:var(--bg);
|
||||
border-bottom:1px solid var(--line); padding:12px 24px;
|
||||
display:flex; align-items:center; gap:22px;
|
||||
}
|
||||
.logo{display:flex; align-items:center; gap:10px; margin-right:8px}
|
||||
.logo-badge{width:36px;height:36px;border-radius:12px;
|
||||
background:linear-gradient(135deg,var(--brand),#64e4dc);
|
||||
display:grid;place-items:center;color:#fff;font-weight:800;box-shadow:var(--soft)}
|
||||
.logo span{font-weight:800;color:var(--brand-600);letter-spacing:.3px}
|
||||
|
||||
.tabs{display:flex; gap:16px; align-items:center; margin-left:auto}
|
||||
.tabs a{color:var(--muted); text-decoration:none; font-weight:600}
|
||||
.tabs a:hover{color:var(--brand-600)}
|
||||
.tabs .active{background:var(--brand); color:#fff; padding:8px 18px;
|
||||
border-radius:999px; box-shadow:0 4px 10px rgba(18,150,143,.25)}
|
||||
|
||||
/* ====== LAYOUT ====== */
|
||||
.wrap{padding:24px; max-width:1300px; margin:0 auto}
|
||||
.grid{display:grid; grid-template-columns: 1fr 320px; gap:24px}
|
||||
.stack{display:grid; gap:18px; grid-template-columns:1fr 1fr}
|
||||
.card{background:var(--bg);border:1px solid var(--line);border-radius:var(--radius);
|
||||
box-shadow:var(--soft); padding:16px}
|
||||
.title{margin:0 0 10px 0; font-weight:800}
|
||||
|
||||
/* Perfil */
|
||||
.profile{display:grid; grid-template-columns:64px 1fr; gap:14px; align-items:center}
|
||||
.avatar{width:64px;height:64px;border-radius:16px;background:#dbe7f1;
|
||||
display:grid;place-items:center;font-weight:800;color:#466;box-shadow:var(--soft)}
|
||||
.kv{display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-top:12px}
|
||||
.kv div{display:flex;justify-content:space-between;background:#fafcff;border:1px solid var(--line);
|
||||
border-radius:10px;padding:8px 10px}
|
||||
|
||||
/* Anéis */
|
||||
.circles{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}
|
||||
.ring{display:grid;place-items:center;gap:8px}
|
||||
.meter{width:120px;height:120px;border-radius:50%;
|
||||
background:radial-gradient(closest-side,var(--bg) 60%,transparent 61% 100%),
|
||||
conic-gradient(#ff5c89 var(--p,75%),#ffe3ec 0);
|
||||
box-shadow:var(--soft)}
|
||||
.ring.blue .meter{
|
||||
background:radial-gradient(closest-side,var(--bg) 60%,transparent 61% 100%),
|
||||
conic-gradient(#2f68ff var(--p,83%),#dfe7ff 0)}
|
||||
.ring b{font-size:18px} .ring span{color:var(--muted);font-size:12px}
|
||||
|
||||
/* Atividade (barras) */
|
||||
.bars{height:140px;display:flex;align-items:flex-end;gap:12px;padding:6px 8px}
|
||||
.bar{flex:1;border-radius:10px;background:linear-gradient(180deg,#ff9fb9,#ffd6e3);box-shadow:var(--soft)}
|
||||
.badge{background:var(--brand-100);color:var(--brand-600);padding:4px 8px;border-radius:999px;font-size:12px;font-weight:700}
|
||||
|
||||
/* Linha (SVG) */
|
||||
.line-wrap{height:220px}
|
||||
.line-svg{width:100%;height:160px;display:block}
|
||||
.axis{stroke:#cfd7e3;stroke-width:1}
|
||||
.stroke-brand{fill:none;stroke:#4b82ff;stroke-width:3;stroke-linecap:round}
|
||||
|
||||
/* Aside: calendário + consultas */
|
||||
.calendar .grid{margin-top:10px;display:grid;grid-template-columns:repeat(7,1fr);gap:6px}
|
||||
.cell{aspect-ratio:1/1;display:grid;place-items:center;background:#fff;border:1px solid var(--line);border-radius:10px}
|
||||
.cell.h{background:transparent;border:0;color:var(--muted);font-weight:700}
|
||||
.cell.m{background:var(--brand-100);border-color:transparent;color:var(--brand-600);font-weight:700}
|
||||
.appt-list{display:flex;flex-direction:column;gap:10px}
|
||||
.appt{display:flex;align-items:center;gap:10px;padding:10px;border-radius:12px;background:#fff;border:1px solid var(--line);box-shadow:var(--soft)}
|
||||
.appt .ic{width:32px;height:32px;border-radius:10px;display:grid;place-items:center;color:#fff;font-size:16px}
|
||||
.appt .time{margin-left:auto;font-weight:800;color:var(--muted)}
|
||||
.brand{
|
||||
display:flex; align-items:center; gap:12px;
|
||||
}
|
||||
.logo{
|
||||
width:36px; height:36px; border-radius:10px;
|
||||
background: linear-gradient(135deg, var(--brand-primary), var(--brand-accent));
|
||||
box-shadow: 0 8px 20px rgba(37,99,235,.45), inset 0 0 10px rgba(255,255,255,.15);
|
||||
}
|
||||
.logo{
|
||||
margin-left: 150px;
|
||||
width:90px;
|
||||
height:auto;
|
||||
}
|
||||
.ola{
|
||||
margin-left: 130px;
|
||||
grid-column: 1 / -1;
|
||||
display:flex; align-items:center; justify-content:space-between;
|
||||
margin-bottom:4px;
|
||||
}
|
||||
.ola .greet{font-size:24px; font-weight:700;}
|
||||
|
||||
.marca { display: flex; align-items: center; gap: .6rem; font-weight: 800; letter-spacing: .4px; }
|
||||
.marca .M { width: 36px; height: 36px; border-radius: 50%; background: linear-gradient(135deg, var(--brand), #4dd7cf); display: grid; place-items: center; color: #fff; font-weight: 700; box-shadow: 0 6px 14px rgba(29,183,174,.35); }
|
||||
/* Responsivo */
|
||||
@media (max-width:1100px){ .grid{grid-template-columns:1fr} }
|
||||
@media (max-width:880px){ .stack{grid-template-columns:1fr} .tabs{gap:10px} }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- ===== NAV SUPERIOR ===== -->
|
||||
<header class="topnav">
|
||||
|
||||
<div class="brand">
|
||||
<img src="logo_HealthOne.jpeg" alt="HealthOne" class="logo">
|
||||
|
||||
<div class="marca">
|
||||
<div class="M">IK</div>
|
||||
<span>Isaac Kauã</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- você pode colocar um campo de busca aqui se quiser -->
|
||||
<nav class="tabs">
|
||||
<a href="#" class="active">Início</a>
|
||||
<a href="agendamento.html" >Marcar Consulta</a>
|
||||
</nav>
|
||||
</header>
|
||||
<div class="ola">
|
||||
<div class="greet">Olá, <span style="color:var(--brand-600)">Isaac Kauã</span> 👋</div>
|
||||
</div>
|
||||
<!-- ===== CONTEÚDO ===== -->
|
||||
<div class="wrap">
|
||||
<div class="grid">
|
||||
|
||||
<!-- coluna principal -->
|
||||
<section class="stack">
|
||||
<article class="card">
|
||||
<h3 class="title">Perfil do Paciente</h3>
|
||||
<div class="profile">
|
||||
<div class="avatar">IK</div>
|
||||
<div>
|
||||
<strong>Isaac Kauã</strong>
|
||||
<div style="color:var(--muted)">862.346.645-47</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="kv">
|
||||
<div><span>Idade</span><b>18 anos</b></div>
|
||||
<div><span>Tipo Sanguíneo</span><b>O+</b></div>
|
||||
<div><span>Altura</span><b>1,90 m</b></div>
|
||||
<div><span>Peso</span><b>100 kg</b></div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="card">
|
||||
<h3 class="title">Indicadores</h3>
|
||||
<div class="circles">
|
||||
<div class="ring" style="--p:75%">
|
||||
<div class="meter" aria-label="Saúde Geral 75%"></div>
|
||||
<b>75%</b><span>Saúde Geral</span>
|
||||
</div>
|
||||
<div class="ring blue" style="--p:83%">
|
||||
<div class="meter" aria-label="Hidratação 83%"></div>
|
||||
<b>83%</b><span>Frequencia de Presença</span>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="card">
|
||||
<h3 class="title">Taxa de Melhora</h3>
|
||||
<div class="bars">
|
||||
<div class="bar" style="height:40%"></div>
|
||||
<div class="bar" style="height:65%"></div>
|
||||
<div class="bar" style="height:55%"></div>
|
||||
<div class="bar" style="height:80%"></div>
|
||||
<div class="bar" style="height:50%"></div>
|
||||
<div class="bar" style="height:35%"></div>
|
||||
<div class="bar" style="height:60%"></div>
|
||||
</div>
|
||||
<div class="badge">Durante Tratamento</div>
|
||||
</article>
|
||||
|
||||
<article class="card line-wrap">
|
||||
<h3 class="title">Condições de Saúde</h3>
|
||||
<svg class="line-svg" viewBox="0 0 600 180" aria-label="Linha de tendência">
|
||||
<line x1="30" y1="150" x2="580" y2="150" class="axis"/>
|
||||
<line x1="30" y1="30" x2="30" y2="150" class="axis"/>
|
||||
<polyline class="stroke-brand"
|
||||
points="30,120 90,140 150,95 210,110 270,70 330,95 390,80 450,120 510,60 570,130"/>
|
||||
</svg>
|
||||
<small style="color:var(--muted)">Jan → Dez</small>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<!-- aside direito -->
|
||||
<aside>
|
||||
<div class="card calendar">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center">
|
||||
<h3 class="title" style="margin:0">Consultas</h3>
|
||||
<span class="badge">Set 2025</span>
|
||||
</div>
|
||||
<div class="grid" id="cal"></div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h3 class="title">Próximas Consultas</h3>
|
||||
<div class="appt-list" id="appts">
|
||||
<div class="appt">
|
||||
<div class="ic" style="background:#2ec5ff">🦷</div>
|
||||
<div><b>Dentista</b><div style="color:var(--muted)"> Quarta - Dra. Gorex Mathew</div></div>
|
||||
<div class="time">09:00</div>
|
||||
</div>
|
||||
<div class="appt">
|
||||
<div class="ic" style="background:#a55cff">❤️</div>
|
||||
<div><b>Cardiologia</b><div style="color:var(--muted)">Quarta - Dr. Craig Gemx</div></div>
|
||||
<div class="time">12:00</div>
|
||||
</div>
|
||||
<div class="appt">
|
||||
<div class="ic" style="background:#ff7a59">🦴</div>
|
||||
<div><b>Ortopedia</b><div style="color:var(--muted)">Quinta - Dr. Bruce Williams</div></div>
|
||||
<div class="time">15:00</div>
|
||||
</div>
|
||||
<div class="appt">
|
||||
<div class="ic" style="background:#22c55e">🩺</div>
|
||||
<div><b>Clínico</b><div style="color:var(--muted)">Quinta - Dra. Kiera Knight</div></div>
|
||||
<div class="time">16:00</div>
|
||||
</div>
|
||||
<div class="appt">
|
||||
<div class="ic" style="background:#ffb020">🧪</div>
|
||||
<div><b>Endocrino</b><div style="color:var(--muted)">Quinta - Dra. Anni Roy</div></div>
|
||||
<div class="time">18:00</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// mini calendário (exemplo: março com marcações)
|
||||
(function(){
|
||||
const el = document.getElementById('cal');
|
||||
const heads = ['S','T','Q','Q','S','S','D'];
|
||||
heads.forEach(h=>{
|
||||
const c=document.createElement('div'); c.textContent=h; c.className='cell h'; el.appendChild(c);
|
||||
});
|
||||
const offset = 0; // domingo
|
||||
const blanks = (7 + offset) % 7;
|
||||
for(let i=0;i<blanks;i++){ const b=document.createElement('div'); b.className='cell'; b.style.visibility='hidden'; el.appendChild(b); }
|
||||
for(let d=1; d<=31; d++){
|
||||
const c=document.createElement('div'); c.className='cell'; c.textContent=d;
|
||||
if([3,10,17,24].includes(d)) c.classList.add('m');
|
||||
el.appendChild(c);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
BIN
HealthOneProject/Lista-agendamento/logo_HealthOne.jpeg
Normal file
|
After Width: | Height: | Size: 53 KiB |
6
HealthOneProject/Readme.txt
Normal file
@ -0,0 +1,6 @@
|
||||
Thanks for downloading this template!
|
||||
|
||||
Template Name: Medicio
|
||||
Template URL: https://bootstrapmade.com/medicio-free-bootstrap-theme/
|
||||
Author: BootstrapMade.com
|
||||
License: https://bootstrapmade.com/license/
|
||||
388
HealthOneProject/Secretaria/copiasecretaria.html
Normal file
@ -0,0 +1,388 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="pt-br">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Histórico de Pacientes • HealthOne</title>
|
||||
<style>
|
||||
:root{
|
||||
--medicio-teal: #3fbbc0;
|
||||
--medicio-teal-600: #34a3a8;
|
||||
--medicio-muted: #6b7280;
|
||||
--medicio-border: #e5e7eb;
|
||||
--medicio-white: #ffffff;
|
||||
--text-dark: #2a2d34;
|
||||
--bg: #f8fafb;
|
||||
--radius: 12px;
|
||||
--shadow: 0 8px 24px rgba(0,0,0,.06);
|
||||
}
|
||||
|
||||
*{box-sizing:border-box}
|
||||
body{
|
||||
margin:0;
|
||||
font-family: Inter, system-ui, -apple-system, "Segoe UI", Roboto, Arial;
|
||||
background: var(--bg);
|
||||
color: var(--text-dark);
|
||||
-webkit-font-smoothing:antialiased;
|
||||
-moz-osx-font-smoothing:grayscale;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
.appbar{
|
||||
background: var(--medicio-white);
|
||||
border-bottom: 1px solid var(--medicio-border);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 20;
|
||||
}
|
||||
.appbar-inner{
|
||||
max-width:1200px; margin:0 auto; padding:14px 20px;
|
||||
display:flex; align-items:center; justify-content:space-between; gap:12px;
|
||||
}
|
||||
.brand{ display:flex; align-items:center; gap:12px; }
|
||||
.logo{
|
||||
width:44px; height:44px; border-radius:50%;
|
||||
box-shadow: 0 0 20px rgba(63,187,192,0.12), 0 0 40px rgba(63,187,192,0.06);
|
||||
background: linear-gradient(135deg, var(--medicio-teal), var(--medicio-teal-600));
|
||||
}
|
||||
.brand h1{ margin:0; font-size:16px; letter-spacing:.2px; }
|
||||
.brand small{ display:block; color:var(--medicio-muted); font-size:12px; margin-top:2px; }
|
||||
|
||||
.wrap{ max-width:1200px; margin:20px auto; padding:0 20px 80px; }
|
||||
|
||||
/* Toolbar / filtros */
|
||||
.toolbar{
|
||||
display:grid;
|
||||
grid-template-columns: 1fr 220px 180px 120px auto;
|
||||
gap:12px; margin-bottom:18px;
|
||||
align-items:center;
|
||||
}
|
||||
@media (max-width:980px){ .toolbar{ grid-template-columns: 1fr 1fr; } }
|
||||
.field{
|
||||
display:flex; align-items:center; gap:10px;
|
||||
background: var(--medicio-white); border:1px solid var(--medicio-border);
|
||||
padding:10px 12px; border-radius:10px;
|
||||
}
|
||||
.field input, .field select{
|
||||
width:100%; border:0; outline:0; background:transparent; color:var(--text-dark); font-size:14px;
|
||||
}
|
||||
label{ font-weight:600; color:var(--medicio-muted); font-size:13px; margin-right:6px; }
|
||||
|
||||
.btn{
|
||||
padding:10px 14px; border-radius:10px; font-weight:700; border:0; cursor:pointer;
|
||||
background:var(--medicio-teal); color:#fff; box-shadow:0 6px 16px rgba(63,187,192,.16);
|
||||
}
|
||||
.btn.secondary{
|
||||
background:#fff; color:var(--text-dark); border:1px solid var(--medicio-border); box-shadow:none;
|
||||
}
|
||||
|
||||
/* Card / tabela estilo Medicio */
|
||||
.card{ background:#fff; border:1px solid var(--medicio-border); border-radius:12px; box-shadow:var(--shadow); }
|
||||
.card-header{ display:flex; align-items:center; justify-content:space-between; padding:16px 18px 10px 18px; border-bottom:1px solid var(--medicio-border); }
|
||||
.card-content{ padding:12px 18px 18px 18px; }
|
||||
|
||||
.table-wrap{ overflow-x:auto; }
|
||||
table{ width:100%; border-collapse:separate; border-spacing:0 10px; min-width:1000px; }
|
||||
thead.thead th{ text-align:left; font-size:12px; color:var(--medicio-muted); padding:8px 12px; text-transform:uppercase; letter-spacing:.6px; }
|
||||
tbody tr.row{ background:#fff; border:1px solid var(--medicio-border); border-radius:10px; }
|
||||
tbody tr.row td{ padding:12px; vertical-align:middle; border-bottom:0; font-size:14px; color:var(--text-dark); }
|
||||
tbody tr.row td.actions{ text-align:right; }
|
||||
|
||||
.badge{ font-size:12px; padding:6px 10px; border-radius:999px; display:inline-block; border:1px solid transparent; }
|
||||
.badge.primary{ background: #eaf8f8; color: #1c7776; border-color:#cdeeea; }
|
||||
.badge.ok{ background:#eaf6ea; color:#1f7a33; border-color:#d7eed5; }
|
||||
.badge.warn{ background:#fff7e6; color:#8a5b07; border-color:#fde8c3; }
|
||||
|
||||
.convenios{ display:flex; gap:8px; flex-wrap:wrap; align-items:center; }
|
||||
|
||||
.actions .btn{ padding:8px 10px; border-radius:8px; font-size:13px; }
|
||||
.page{ padding:8px 12px; border-radius:999px; border:1px solid var(--medicio-border); background:#fff; cursor:pointer; }
|
||||
|
||||
.empty{ text-align:center; color:var(--medicio-muted); padding:28px 12px; }
|
||||
|
||||
/* responsivo: compacta colunas pequenas */
|
||||
@media (max-width:720px){
|
||||
thead.thead th:nth-child(3), /* Telefone */
|
||||
thead.thead th:nth-child(4), /* Cidade */
|
||||
thead.thead th:nth-child(5), /* Estado */
|
||||
thead.thead th:nth-child(6), /* Convênio */
|
||||
thead.thead th:nth-child(7), /* VIP */
|
||||
thead.thead th:nth-child(10), /* Último atendimento */
|
||||
thead.thead th:nth-child(11) /* Próximo atendimento */ { display:none; }
|
||||
tbody tr.row td:nth-child(3),
|
||||
tbody tr.row td:nth-child(4),
|
||||
tbody tr.row td:nth-child(5),
|
||||
tbody tr.row td:nth-child(6),
|
||||
tbody tr.row td:nth-child(7),
|
||||
tbody tr.row td:nth-child(10),
|
||||
tbody tr.row td:nth-child(11) { display:none; }
|
||||
table{ min-width:700px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="appbar">
|
||||
<div class="appbar-inner">
|
||||
<div class="brand">
|
||||
<div class="logo" aria-hidden="true"></div>
|
||||
<div>
|
||||
<h1>HealthOne</h1>
|
||||
<small>Histórico de Pacientes</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<main class="wrap">
|
||||
<!-- filtros -->
|
||||
<div class="toolbar">
|
||||
<div class="field" style="min-width:220px;">
|
||||
<label for="pacienteSelect" style="min-width:90px">Paciente</label>
|
||||
<select id="pacienteSelect">
|
||||
<option value="">-- Escolha --</option>
|
||||
<option value="1">João da Silva</option>
|
||||
<option value="2">Maria Ferreira</option>
|
||||
<option value="3">Carlos Souza</option>
|
||||
<option value="4">Ana Paula</option>
|
||||
<option value="5">Lucas Lima</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="dataSelect">Dia</label>
|
||||
<input type="date" id="dataSelect" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="mesSelect">Mês</label>
|
||||
<input type="month" id="mesSelect" />
|
||||
</div>
|
||||
|
||||
<div style="display:flex; gap:8px; justify-content:flex-end;">
|
||||
<button id="limparFiltros" class="btn secondary">Limpar filtros</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- tabela -->
|
||||
<section class="card" aria-label="Histórico de consultas">
|
||||
<div class="card-header">
|
||||
<h2>Histórico de Consultas</h2>
|
||||
<div style="color:var(--medicio-muted); font-size:13px">Use os filtros acima para refinar.</div>
|
||||
</div>
|
||||
|
||||
<div class="card-content">
|
||||
<div class="table-wrap">
|
||||
<table id="Consultas" aria-describedby="Tabela de histórico">
|
||||
<thead class="thead">
|
||||
<tr>
|
||||
<th>CPF</th>
|
||||
<th>Paciente</th>
|
||||
<th>Telefone</th>
|
||||
<th>Cidade</th>
|
||||
<th>Estado</th>
|
||||
<th>Convênio</th>
|
||||
<th>VIP</th>
|
||||
<th>Médico</th>
|
||||
<th>Data da Consulta</th>
|
||||
<th>Último atendimento</th>
|
||||
<th>Próximo atendimento</th>
|
||||
<th>Motivo da Consulta</th>
|
||||
<th>Diagnóstico</th>
|
||||
<th>Tratamento</th>
|
||||
<th>Relatório</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="row" data-paciente="1" data-data="2025-09-03 09:30" data-medico="Dr. Almeida" data-cpf="123.456.789-00">
|
||||
<td>123.456.789-00</td>
|
||||
<td>João da Silva</td>
|
||||
<td>(79) 99893-2499</td>
|
||||
<td>Aracaju</td>
|
||||
<td>Sergipe</td>
|
||||
<td>Particular</td>
|
||||
<td>-</td>
|
||||
<td>Dr. Almeida</td>
|
||||
<td>2025-09-03 09:30</td>
|
||||
<td>2025-03-11 11:00</td>
|
||||
<td>2025-09-19 15:00</td>
|
||||
<td>Dor no peito</td>
|
||||
<td>Angina estável</td>
|
||||
<td>NTG conforme protocolo</td>
|
||||
<td>Relatório: observou-se estabilização com medicação.</td>
|
||||
</tr>
|
||||
|
||||
<tr class="row" data-paciente="1" data-data="2025-04-15 11:00" data-medico="Dra. Beatriz" data-cpf="123.456.789-00">
|
||||
<td>123.456.789-00</td>
|
||||
<td>João da Silva</td>
|
||||
<td>(79) 99893-2499</td>
|
||||
<td>Aracaju</td>
|
||||
<td>Sergipe</td>
|
||||
<td>Particular</td>
|
||||
<td>-</td>
|
||||
<td>Dra. Beatriz</td>
|
||||
<td>2025-04-15 11:00</td>
|
||||
<td>2024-12-20 09:00</td>
|
||||
<td>2025-10-01 15:30</td>
|
||||
<td>Consulta de rotina</td>
|
||||
<td>Sem alterações</td>
|
||||
<td>Recomendação: acompanhamento semestral</td>
|
||||
<td>Relatório: sem intercorrências.</td>
|
||||
</tr>
|
||||
|
||||
<tr class="row" data-paciente="2" data-data="2025-07-10 14:00" data-medico="Dr. Almeida" data-cpf="987.654.321-11">
|
||||
<td>987.654.321-11</td>
|
||||
<td>Maria Ferreira</td>
|
||||
<td>(79) 99892-6363</td>
|
||||
<td>Aracaju</td>
|
||||
<td>Sergipe</td>
|
||||
<td>SUS</td>
|
||||
<td>-</td>
|
||||
<td>Dr. Almeida</td>
|
||||
<td>2025-07-10 14:00</td>
|
||||
<td>2024-06-26 14:30</td>
|
||||
<td>2025-08-19 15:00</td>
|
||||
<td>Cansaço frequente</td>
|
||||
<td>Anemia leve</td>
|
||||
<td>Suplemento de ferro</td>
|
||||
<td>Relatório: sugerido retorno em 3 meses.</td>
|
||||
</tr>
|
||||
|
||||
<tr class="row" data-paciente="3" data-data="2025-11-18 10:00" data-medico="Dra. Beatriz" data-cpf="111.222.333-44">
|
||||
<td>111.222.333-44</td>
|
||||
<td>Carlos Souza</td>
|
||||
<td>(79) 99983-0093</td>
|
||||
<td>São Cristóvão</td>
|
||||
<td>Sergipe</td>
|
||||
<td>Unimed</td>
|
||||
<td>-</td>
|
||||
<td>Dra. Beatriz</td>
|
||||
<td>2025-11-18 10:00</td>
|
||||
<td>2024-12-30 08:40</td>
|
||||
<td>2025-12-05 10:00</td>
|
||||
<td>Febre alta</td>
|
||||
<td>Infecção viral</td>
|
||||
<td>Repouso e hidratação</td>
|
||||
<td>Relatório: melhora após 5 dias.</td>
|
||||
</tr>
|
||||
|
||||
<tr class="row" data-paciente="4" data-data="2025-09-22 16:30" data-medico="Dr. Carlos" data-cpf="555.666.777-88">
|
||||
<td>555.666.777-88</td>
|
||||
<td>Ana Paula</td>
|
||||
<td>(79) 99890-9248</td>
|
||||
<td>Itabaiana</td>
|
||||
<td>Sergipe</td>
|
||||
<td>Particular</td>
|
||||
<td>-</td>
|
||||
<td>Dr. Carlos</td>
|
||||
<td>2025-09-22 16:30</td>
|
||||
<td>2024-03-14 10:45</td>
|
||||
<td>2025-10-10 09:00</td>
|
||||
<td>Consulta de rotina</td>
|
||||
<td>Hipertensão controlada</td>
|
||||
<td>Manter medicação</td>
|
||||
<td>Relatório: pressão arterial estável.</td>
|
||||
</tr>
|
||||
|
||||
<tr class="row" data-paciente="5" data-data="2025-10-25 09:00" data-medico="Dr. Almeida" data-cpf="999.888.777-66">
|
||||
<td>999.888.777-66</td>
|
||||
<td>Lucas Lima</td>
|
||||
<td>(79) 99888-7777</td>
|
||||
<td>Aracaju</td>
|
||||
<td>Sergipe</td>
|
||||
<td>SUS</td>
|
||||
<td>-</td>
|
||||
<td>Dr. Almeida</td>
|
||||
<td>2025-10-25 09:00</td>
|
||||
<td>2024-09-21 11:50</td>
|
||||
<td>2025-11-25 09:30</td>
|
||||
<td>Dor de cabeça</td>
|
||||
<td>Enxaqueca</td>
|
||||
<td>Prescrição de analgésicos</td>
|
||||
<td>Relatório: acompanhamento mensal recomendado.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="empty note" id="note">Selecione um paciente, um dia ou um mês para filtrar o histórico de consultas.</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
const pacienteSelect = document.getElementById("pacienteSelect");
|
||||
const dataSelect = document.getElementById("dataSelect");
|
||||
const mesSelect = document.getElementById("mesSelect");
|
||||
const linhas = document.querySelectorAll("#Consultas tbody tr");
|
||||
const note = document.getElementById('note');
|
||||
|
||||
function filtrarConsultas() {
|
||||
const pacienteId = pacienteSelect.value;
|
||||
const dataEscolhida = dataSelect.value; // yyyy-mm-dd
|
||||
const mesEscolhido = mesSelect.value; // yyyy-mm
|
||||
|
||||
let anyVisible = false;
|
||||
|
||||
linhas.forEach(linha => {
|
||||
const linhaPaciente = linha.getAttribute("data-paciente");
|
||||
const dataConsulta = linha.getAttribute("data-data").slice(0, 10); // yyyy-mm-dd
|
||||
|
||||
let mostrar = true;
|
||||
|
||||
// Filtrar por paciente
|
||||
if (pacienteId && linhaPaciente !== pacienteId) {
|
||||
mostrar = false;
|
||||
}
|
||||
|
||||
// Filtrar por dia (dataSelect)
|
||||
if (dataEscolhida) {
|
||||
if (dataConsulta !== dataEscolhida) {
|
||||
mostrar = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Filtrar por mês (mesSelect)
|
||||
if (mesEscolhido) {
|
||||
if (!dataConsulta.startsWith(mesEscolhido)) {
|
||||
mostrar = false;
|
||||
}
|
||||
}
|
||||
|
||||
linha.style.display = mostrar ? "" : "none";
|
||||
if(mostrar) anyVisible = true;
|
||||
});
|
||||
|
||||
note.style.display = anyVisible ? 'none' : 'block';
|
||||
}
|
||||
|
||||
// Eventos para disparar o filtro (mantendo comportamento original: limpar outros selects)
|
||||
pacienteSelect.addEventListener("change", () => {
|
||||
dataSelect.value = "";
|
||||
mesSelect.value = "";
|
||||
filtrarConsultas();
|
||||
});
|
||||
|
||||
dataSelect.addEventListener("change", () => {
|
||||
pacienteSelect.value = "";
|
||||
mesSelect.value = "";
|
||||
filtrarConsultas();
|
||||
});
|
||||
|
||||
mesSelect.addEventListener("change", () => {
|
||||
pacienteSelect.value = "";
|
||||
dataSelect.value = "";
|
||||
filtrarConsultas();
|
||||
});
|
||||
|
||||
document.getElementById('limparFiltros').addEventListener('click', () => {
|
||||
pacienteSelect.value = "";
|
||||
dataSelect.value = "";
|
||||
mesSelect.value = "";
|
||||
filtrarConsultas();
|
||||
});
|
||||
|
||||
// iniciar com todos visíveis
|
||||
filtrarConsultas();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
304
HealthOneProject/Secretaria/secretaria.html
Normal file
@ -0,0 +1,304 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="pt-br">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Histórico de Pacientes • HealthOne</title>
|
||||
<style>
|
||||
:root{
|
||||
--medicio-teal: #3fbbc0;
|
||||
--medicio-teal-600: #34a3a8;
|
||||
--medicio-muted: #6b7280;
|
||||
--medicio-border: #e5e7eb;
|
||||
--medicio-white: #ffffff;
|
||||
--text-dark: #2a2d34;
|
||||
--bg: #f8fafb;
|
||||
--radius: 12px;
|
||||
--shadow: 0 8px 24px rgba(0,0,0,.06);
|
||||
}
|
||||
*{box-sizing:border-box}
|
||||
body{
|
||||
margin:0;
|
||||
font-family: Inter, system-ui, -apple-system, "Segoe UI", Roboto, Arial;
|
||||
background: var(--bg);
|
||||
color: var(--text-dark);
|
||||
-webkit-font-smoothing:antialiased;
|
||||
-moz-osx-font-smoothing:grayscale;
|
||||
}
|
||||
.appbar{
|
||||
background: var(--medicio-white);
|
||||
border-bottom: 1px solid var(--medicio-border);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 20;
|
||||
}
|
||||
.appbar-inner{
|
||||
max-width:1200px; margin:0 auto; padding:14px 20px;
|
||||
display:flex; align-items:center; justify-content:space-between; gap:12px;
|
||||
}
|
||||
.brand{ display:flex; align-items:center; gap:12px; }
|
||||
.logo{
|
||||
width:44px; height:44px; border-radius:50%;
|
||||
box-shadow: 0 0 20px rgba(63,187,192,0.12), 0 0 40px rgba(63,187,192,0.06);
|
||||
background: linear-gradient(135deg, var(--medicio-teal), var(--medicio-teal-600));
|
||||
}
|
||||
.brand h1{ margin:0; font-size:16px; letter-spacing:.2px; }
|
||||
.brand small{ display:block; color:var(--medicio-muted); font-size:12px; margin-top:2px; }
|
||||
.wrap{ max-width:1200px; margin:20px auto; padding:0 20px 80px; }
|
||||
.toolbar{
|
||||
display:grid;
|
||||
grid-template-columns: 1fr 220px 180px 120px auto;
|
||||
gap:12px; margin-bottom:18px;
|
||||
align-items:center;
|
||||
}
|
||||
@media (max-width:980px){ .toolbar{ grid-template-columns: 1fr 1fr; } }
|
||||
.field{
|
||||
display:flex; align-items:center; gap:10px;
|
||||
background: var(--medicio-white); border:1px solid var(--medicio-border);
|
||||
padding:10px 12px; border-radius:10px;
|
||||
}
|
||||
.field input, .field select{
|
||||
width:100%; border:0; outline:0; background:transparent; color:var(--text-dark); font-size:14px;
|
||||
}
|
||||
label{ font-weight:600; color:var(--medicio-muted); font-size:13px; margin-right:6px; }
|
||||
.btn{
|
||||
padding:10px 14px; border-radius:10px; font-weight:700; border:0; cursor:pointer;
|
||||
background:var(--medicio-teal); color:#fff; box-shadow:0 6px 16px rgba(63,187,192,.16);
|
||||
}
|
||||
.btn.secondary{
|
||||
background:#fff; color:var(--text-dark); border:1px solid var(--medicio-border); box-shadow:none;
|
||||
}
|
||||
.card{ background:#fff; border:1px solid var(--medicio-border); border-radius:12px; box-shadow:var(--shadow); }
|
||||
.card-header{ display:flex; align-items:center; justify-content:space-between; padding:16px 18px 10px 18px; border-bottom:1px solid var(--medicio-border); }
|
||||
.card-content{ padding:12px 18px 18px 18px; }
|
||||
.table-wrap{ overflow-x:auto; }
|
||||
table{ width:100%; border-collapse:separate; border-spacing:0 10px; min-width:1000px; }
|
||||
thead.thead th{ text-align:left; font-size:12px; color:var(--medicio-muted); padding:8px 12px; text-transform:uppercase; letter-spacing:.6px; }
|
||||
tbody tr.row{ background:#fff; border:1px solid var(--medicio-border); border-radius:10px; }
|
||||
tbody tr.row td{ padding:12px; vertical-align:middle; border-bottom:0; font-size:14px; color:var(--text-dark); }
|
||||
tbody tr.row td.actions{ text-align:right; }
|
||||
.empty{ text-align:center; color:var(--medicio-muted); padding:28px 12px; }
|
||||
@media (max-width:720px){
|
||||
thead.thead th:nth-child(3),
|
||||
thead.thead th:nth-child(4),
|
||||
thead.thead th:nth-child(5),
|
||||
thead.thead th:nth-child(6),
|
||||
thead.thead th:nth-child(7),
|
||||
thead.thead th:nth-child(9),
|
||||
thead.thead th:nth-child(10) { display:none; }
|
||||
tbody tr.row td:nth-child(3),
|
||||
tbody tr.row td:nth-child(4),
|
||||
tbody tr.row td:nth-child(5),
|
||||
tbody tr.row td:nth-child(6),
|
||||
tbody tr.row td:nth-child(7),
|
||||
tbody tr.row td:nth-child(9),
|
||||
tbody tr.row td:nth-child(10) { display:none; }
|
||||
table{ min-width:700px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="appbar">
|
||||
<div class="appbar-inner">
|
||||
<div class="brand">
|
||||
<div class="logo" aria-hidden="true"></div>
|
||||
<div>
|
||||
<h1>HealthOne</h1>
|
||||
<small>Histórico de Pacientes</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<main class="wrap">
|
||||
<div class="toolbar">
|
||||
<div class="field" style="min-width:220px;">
|
||||
<label for="pacienteSelect" style="min-width:90px">Paciente</label>
|
||||
<select id="pacienteSelect">
|
||||
<option value="">-- Escolha --</option>
|
||||
<option value="1">João da Silva</option>
|
||||
<option value="2">Maria Ferreira</option>
|
||||
<option value="3">Carlos Souza</option>
|
||||
<option value="4">Ana Paula</option>
|
||||
<option value="5">Lucas Lima</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="dataSelect">Dia</label>
|
||||
<input type="date" id="dataSelect" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="mesSelect">Mês</label>
|
||||
<input type="month" id="mesSelect" />
|
||||
</div>
|
||||
|
||||
<div style="display:flex; gap:8px; justify-content:flex-end;">
|
||||
<button id="limparFiltros" class="btn secondary">Limpar filtros</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="card" aria-label="Histórico de consultas">
|
||||
<div class="card-header">
|
||||
<h2>Histórico de Consultas</h2>
|
||||
<div style="color:var(--medicio-muted); font-size:13px">Use os filtros acima para refinar.</div>
|
||||
</div>
|
||||
|
||||
<div class="card-content">
|
||||
<div class="table-wrap">
|
||||
<table id="Consultas" aria-describedby="Tabela de histórico">
|
||||
<thead class="thead">
|
||||
<tr>
|
||||
<th>CPF</th>
|
||||
<th>Paciente</th>
|
||||
<th>Telefone</th>
|
||||
<th>Cidade</th>
|
||||
<th>Estado</th>
|
||||
<th>VIP</th>
|
||||
<th>Médico</th>
|
||||
<th>Data da Consulta</th>
|
||||
<th>Último atendimento</th>
|
||||
<th>Próximo atendimento</th>
|
||||
<th>Motivo da Consulta</th>
|
||||
<th>Diagnóstico</th>
|
||||
<th>Tratamento</th>
|
||||
<th>Relatório</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="consultasBody"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="empty note" id="note">Selecione um paciente, um dia ou um mês para filtrar o histórico de consultas.</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
const consultasBody = document.getElementById('consultasBody');
|
||||
const note = document.getElementById('note');
|
||||
|
||||
function carregarConsultas() {
|
||||
const consultas = JSON.parse(localStorage.getItem('healthone_consultas') || '[]');
|
||||
|
||||
if (consultas.length === 0) {
|
||||
consultasBody.innerHTML = '';
|
||||
note.textContent = 'Nenhuma consulta agendada.';
|
||||
note.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
|
||||
const note = document.getElementById('note');
|
||||
|
||||
note.style.display = 'none';
|
||||
|
||||
consultasBody.innerHTML = consultas.map(c => {
|
||||
// Dados fictícios para paciente, você pode adaptar conforme sua base
|
||||
const pacienteNome = "Paciente não informado";
|
||||
const cpf = "-";
|
||||
const telefone = "-";
|
||||
const cidade = "-";
|
||||
const estado = "-";
|
||||
const vip = "-";
|
||||
const motivo = "-";
|
||||
const diagnostico = "-";
|
||||
const tratamento = "-";
|
||||
const relatorio = "-";
|
||||
|
||||
return `
|
||||
<tr class="row" data-paciente="" data-data="${c.dataHora}" data-medico="${c.medicoNome}" data-cpf="${cpf}">
|
||||
<td>${cpf}</td>
|
||||
<td>${pacienteNome}</td>
|
||||
<td>${telefone}</td>
|
||||
<td>${cidade}</td>
|
||||
<td>${estado}</td>
|
||||
<td>${vip}</td>
|
||||
<td>${c.medicoNome}</td>
|
||||
<td>${c.dataHora}</td>
|
||||
<td>-</td>
|
||||
<td>-</td>
|
||||
<td>${motivo}</td>
|
||||
<td>${diagnostico}</td>
|
||||
<td>${tratamento}</td>
|
||||
<td>${relatorio}</td>
|
||||
</tr>
|
||||
`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
carregarConsultas();
|
||||
|
||||
window.addEventListener('storage', (event) => {
|
||||
if(event.key === 'healthone_consultas'){
|
||||
carregarConsultas();
|
||||
}
|
||||
});
|
||||
|
||||
const pacienteSelect = document.getElementById("pacienteSelect");
|
||||
const dataSelect = document.getElementById("dataSelect");
|
||||
const mesSelect = document.getElementById("mesSelect");
|
||||
|
||||
function filtrarConsultas() {
|
||||
const linhas = document.querySelectorAll("#Consultas tbody tr");
|
||||
const pacienteId = pacienteSelect.value;
|
||||
const dataEscolhida = dataSelect.value; // yyyy-mm-dd
|
||||
const mesEscolhido = mesSelect.value; // yyyy-mm
|
||||
|
||||
let anyVisible = false;
|
||||
|
||||
linhas.forEach(linha => {
|
||||
const linhaPaciente = linha.getAttribute("data-paciente");
|
||||
const dataConsulta = linha.getAttribute("data-data").slice(0, 10); // yyyy-mm-dd
|
||||
|
||||
let mostrar = true;
|
||||
|
||||
if (pacienteId && linhaPaciente !== pacienteId) {
|
||||
mostrar = false;
|
||||
}
|
||||
|
||||
if (dataEscolhida && dataConsulta !== dataEscolhida) {
|
||||
mostrar = false;
|
||||
}
|
||||
|
||||
if (mesEscolhido && !dataConsulta.startsWith(mesEscolhido)) {
|
||||
mostrar = false;
|
||||
}
|
||||
|
||||
linha.style.display = mostrar ? "" : "none";
|
||||
if(mostrar) anyVisible = true;
|
||||
});
|
||||
|
||||
note.style.display = anyVisible ? 'none' : 'block';
|
||||
}
|
||||
|
||||
pacienteSelect.addEventListener("change", () => {
|
||||
dataSelect.value = "";
|
||||
mesSelect.value = "";
|
||||
filtrarConsultas();
|
||||
});
|
||||
|
||||
dataSelect.addEventListener("change", () => {
|
||||
pacienteSelect.value = "";
|
||||
mesSelect.value = "";
|
||||
filtrarConsultas();
|
||||
});
|
||||
|
||||
mesSelect.addEventListener("change", () => {
|
||||
pacienteSelect.value = "";
|
||||
dataSelect.value = "";
|
||||
filtrarConsultas();
|
||||
});
|
||||
|
||||
document.getElementById('limparFiltros').addEventListener('click', () => {
|
||||
pacienteSelect.value = "";
|
||||
dataSelect.value = "";
|
||||
mesSelect.value = "";
|
||||
filtrarConsultas();
|
||||
});
|
||||
|
||||
// iniciar com todos visíveis
|
||||
filtrarConsultas();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
210
HealthOneProject/assets/css/crud-paciente.css
Normal file
@ -0,0 +1,210 @@
|
||||
:root {
|
||||
--brand: #1db7ae;
|
||||
--brand-600: #12968f;
|
||||
--brand-100: #e7f7f6;
|
||||
--ink: #24323f;
|
||||
--muted: #6b7a88;
|
||||
--line: #e6eaef;
|
||||
--bg: #ffffff;
|
||||
--danger: #e55353;
|
||||
--warning: #f59e0b;
|
||||
--success: #22c55e;
|
||||
--shadow: 0 10px 20px rgba(15, 23, 42, .06);
|
||||
--radius: 14px;
|
||||
}
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
body { margin: 0; font-family: Inter, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji"; color: var(--ink); background: #f6f8fb; }
|
||||
a { color: inherit; text-decoration: none; }
|
||||
button { font: inherit; }
|
||||
|
||||
.topbar { background: var(--brand); color: #fff; font-size: .9rem; }
|
||||
.topbar .wrap { max-width: 1200px; margin: 0 auto; padding: .5rem 1rem; display: flex; gap: 1rem; align-items: center; justify-content: space-between; }
|
||||
.topbar small { opacity: .95; }
|
||||
|
||||
header { background: #fff; box-shadow: var(--shadow); position: sticky; top: 0; z-index: 30; }
|
||||
header .wrap { max-width: 1200px; margin: 0 auto; padding: .9rem 1rem; display: flex; align-items: center; justify-content: space-between; }
|
||||
.brand { display: flex; align-items: center; gap: .6rem; font-weight: 800; letter-spacing: .4px; }
|
||||
.brand .logo { width: 36px; height: 36px; border-radius: 50%; background: linear-gradient(135deg, var(--brand), #4dd7cf); display: grid; place-items: center; color: #fff; font-weight: 700; box-shadow: 0 6px 14px rgba(29,183,174,.35); }
|
||||
nav { display: flex; gap: 1.2rem; color: var(--muted); font-weight: 600; }
|
||||
.cta { background: var(--brand); color: #fff; padding: .6rem 1rem; border-radius: 999px; box-shadow: 0 10px 18px rgba(29,183,174,.25); transition: .2s ease; }
|
||||
.cta:hover { background: var(--brand-600); transform: translateY(-1px); }
|
||||
|
||||
.container { max-width: 1200px; margin: 28px auto; padding: 0 1rem 4rem; }
|
||||
|
||||
.card { background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); }
|
||||
.card .head { padding: 1rem 1.2rem; border-bottom: 1px solid var(--line); display: flex; gap: 1rem; align-items: center; justify-content: space-between; }
|
||||
.title { display: flex; gap: .8rem; align-items: center; }
|
||||
.title h1 { margin: 0; font-size: 1.25rem; }
|
||||
.badge { background: var(--brand-100); color: var(--brand-600); font-weight: 700; padding: .2rem .5rem; border-radius: 6px; font-size: .75rem; }
|
||||
|
||||
.toolbar { display: grid; grid-template-columns: 1fr auto; gap: .8rem; width: 100%; }
|
||||
.search { display: flex; align-items: center; gap: .6rem; background: #f9fbfd; border: 1px solid var(--line); padding: .55rem .8rem; border-radius: 999px; }
|
||||
.search input { all: unset; width: 100%; color: var(--ink); }
|
||||
.btn { display: inline-flex; gap: .5rem; align-items: center; border: 1px solid transparent; border-radius: 999px; padding: .65rem 1rem; font-weight: 700; cursor: pointer; transition: .2s ease; }
|
||||
.btn.primary { background: var(--brand); color: #fff; box-shadow: 0 10px 18px rgba(29,183,174,.25); }
|
||||
.btn.primary:hover { background: var(--brand-600); transform: translateY(-1px); }
|
||||
|
||||
.table { width: 100%; border-collapse: collapse; }
|
||||
.table thead th { text-align: left; font-size: .8rem; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); background: #fbfdff; border-bottom: 1px solid var(--line); padding: .9rem .9rem; }
|
||||
.table tbody td { padding: .9rem .9rem; border-bottom: 1px solid var(--line); vertical-align: middle; }
|
||||
.table tbody tr:hover { background: #fcfefe; }
|
||||
|
||||
.actions { display: inline-flex; gap: .35rem; }
|
||||
.icon-btn { --bg: #f2f6fb; --bd: var(--line); display: inline-grid; place-items: center; width: 34px; height: 34px; border-radius: 10px; border: 1px solid var(--bd); background: var(--bg); transition: .2s ease; }
|
||||
.icon-btn:hover { transform: translateY(-1px); box-shadow: var(--shadow); }
|
||||
|
||||
.table-footer { display: flex; align-items: center; justify-content: space-between; padding: 1rem 1.2rem; }
|
||||
.pagination { display: inline-flex; gap: .4rem; }
|
||||
.page-btn, .page { min-width: 36px; height: 36px; border-radius: 10px; border: 1px solid var(--line); display: grid; place-items: center; padding: 0 .6rem; background:#fff; cursor:pointer }
|
||||
.page-btn.active, .page.is-active { background: var(--brand); color: #fff; border-color: transparent; box-shadow: 0 10px 18px rgba(29,183,174,.25); }
|
||||
.col-actions{ text-align:right }
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.toolbar { grid-template-columns: 1fr; }
|
||||
.table thead { display: none; }
|
||||
.table, .table tbody, .table tr, .table td { display: block; width: 100%; }
|
||||
.table tbody tr { border-bottom: 1px solid var(--line); padding: .6rem 0; }
|
||||
.table tbody td { border-bottom: none; display: grid; grid-template-columns: 30% 1fr; gap: .6rem; padding: .5rem .9rem; }
|
||||
.actions { justify-content: flex-end; }
|
||||
}
|
||||
:root{
|
||||
--brand: #1db7ae;
|
||||
--brand-600:#12968f;
|
||||
--brand-100:#e7f7f6;
|
||||
--ink:#24323f;
|
||||
--muted:#6b7a88;
|
||||
--line:#e6eaef;
|
||||
--bg:#ffffff;
|
||||
--shadow: 0 20px 60px rgba(18,150,143,.22);
|
||||
}
|
||||
|
||||
.overlay{
|
||||
position: fixed; inset: 0;
|
||||
background: rgba(14, 23, 29, .56);
|
||||
display: none; align-items: center; justify-content: center;
|
||||
padding: 24px;
|
||||
z-index: 999;
|
||||
}
|
||||
.overlay[aria-hidden="false"]{ display:flex; }
|
||||
|
||||
.carteirinha-wrap{
|
||||
width: min(820px, 96vw);
|
||||
perspective: 1400px;
|
||||
position: relative;
|
||||
animation: overlayIn .18s ease-out;
|
||||
}
|
||||
|
||||
@keyframes overlayIn {
|
||||
from{ transform: translateY(8px); opacity:.0}
|
||||
to{ transform: translateY(0); opacity:1}
|
||||
}
|
||||
|
||||
.close-btn{
|
||||
position: absolute;
|
||||
top: -14px;
|
||||
right: -14px;
|
||||
width: 40px; height: 40px;
|
||||
border: none; border-radius: 12px;
|
||||
background: #fff;
|
||||
box-shadow: 0 8px 20px rgba(0,0,0,.18);
|
||||
font-size: 28px; line-height: 40px;
|
||||
color: #6b7a88; cursor: pointer;
|
||||
z-index: 1010; }
|
||||
|
||||
.close-btn:hover{ transform: translateY(-1px); }
|
||||
|
||||
.carteirinha{
|
||||
background: var(--bg);
|
||||
border-radius: 20px;
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
transform: rotateX(14deg) rotateY(-8deg) scale(.96);
|
||||
transform-origin: 50% 60%;
|
||||
animation: cardEnter .35s cubic-bezier(.22,.9,.27,1.05) forwards;
|
||||
}
|
||||
|
||||
@keyframes cardEnter{
|
||||
to { transform: rotateX(0) rotateY(0) scale(1); }
|
||||
}
|
||||
|
||||
.cart-header{
|
||||
display:flex; align-items:center; gap:12px;
|
||||
background: linear-gradient(135deg, var(--brand), #15a6a0);
|
||||
color:#fff; padding: 20px 22px;
|
||||
}
|
||||
.logo-dot{ width:12px; height:12px; border-radius:50%; background:#fff; opacity:.9 }
|
||||
.cart-header h3{ margin:0; font-weight:700; letter-spacing:.3px }
|
||||
.tag{
|
||||
margin-left:auto; background: rgba(255,255,255,.18);
|
||||
border:1px solid rgba(255,255,255,.35);
|
||||
padding:6px 10px; border-radius:999px; font-size:12px
|
||||
}
|
||||
|
||||
.cart-body{ padding: 20px 22px; display:grid; grid-template-columns: 120px 1fr; gap: 18px; }
|
||||
.avatar{
|
||||
position: relative; width:110px; height:110px; border-radius:16px;
|
||||
background: var(--brand-100);
|
||||
display:grid; place-items:center; font-weight:700; color:var(--brand-600);
|
||||
isolation:isolate;
|
||||
}
|
||||
.avatar-ring{
|
||||
position:absolute; inset:-6px;
|
||||
border-radius:20px; border: 2px dashed var(--brand-600);
|
||||
opacity:.25; animation: spin 10s linear infinite;
|
||||
z-index: -1;
|
||||
}
|
||||
@keyframes spin { to{ transform: rotate(360deg); } }
|
||||
.avatar-iniciais{ font-size:28px }
|
||||
|
||||
.grid{
|
||||
display:grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 14px;
|
||||
}
|
||||
.field label{
|
||||
display:block; font-size:12px; color: var(--muted); margin-bottom:4px
|
||||
}
|
||||
.field p{
|
||||
background:#fff; border:1px solid var(--line);
|
||||
border-radius:12px; padding:10px 12px; margin:0; color:var(--ink);
|
||||
}
|
||||
|
||||
.obs{ grid-column: 1/-1; }
|
||||
.obs label{ display:block; font-size:12px; color:var(--muted); margin:10px 0 6px; }
|
||||
.obs p{
|
||||
margin:0; background:#fff; border:1px dashed var(--line);
|
||||
border-radius:12px; padding:12px; min-height:56px; color:var(--ink)
|
||||
}
|
||||
|
||||
.cart-footer{
|
||||
display:flex; align-items:center; gap:16px; justify-content:space-between;
|
||||
padding: 12px 18px 18px;
|
||||
border-top:1px solid var(--line);
|
||||
background: #fafdfd;
|
||||
}
|
||||
.chips{ display:flex; gap:10px; flex-wrap:wrap }
|
||||
.chip{
|
||||
background: var(--brand-100); color: var(--brand-600);
|
||||
border:1px solid #cbeeed; padding:6px 10px; border-radius:999px; font-size:12px;
|
||||
}
|
||||
.chip.outline{
|
||||
background: #fff; border:1px dashed #cbeeed; color: var(--brand-600);
|
||||
}
|
||||
.actions{ display:flex; gap:10px }
|
||||
button.primary, button.ghost{
|
||||
border-radius:12px; padding:10px 14px; border:1px solid var(--line);
|
||||
cursor:pointer; font-weight:600;
|
||||
}
|
||||
button.primary{ background: var(--brand); color:#fff; border-color: transparent; }
|
||||
button.primary:hover{ background: var(--brand-600); }
|
||||
button.ghost{ background:#fff; color: var(--ink); }
|
||||
button.ghost:hover{ border-color: var(--brand-600); color: var(--brand-600); }
|
||||
|
||||
/* Responsivo */
|
||||
@media (max-width: 720px){
|
||||
.cart-body{ grid-template-columns: 1fr; }
|
||||
.grid{ grid-template-columns: 1fr 1fr; }
|
||||
}
|
||||
@media (max-width: 440px){
|
||||
.grid{ grid-template-columns: 1fr; }
|
||||
}
|
||||
84
HealthOneProject/assets/css/editar-laudo.css
Normal file
@ -0,0 +1,84 @@
|
||||
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f7f9fb;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-bottom: 20px;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.editor-toolbar {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.editor-toolbar button {
|
||||
background: #00bcd4;
|
||||
border: none;
|
||||
padding: 8px;
|
||||
margin-right: 5px;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
#laudo-conteudo {
|
||||
width: 100%;
|
||||
height: 250px;
|
||||
border: 1px solid #ccc;
|
||||
padding: 10px;
|
||||
background: white;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.opcoes {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.opcoes input,
|
||||
.opcoes select,
|
||||
.opcoes button {
|
||||
padding: 8px;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.btn-salvar {
|
||||
background: #4caf50;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-cancelar {
|
||||
background: #f44336;
|
||||
color: white;
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.status {
|
||||
font-weight: bold;
|
||||
margin-top: 5px;
|
||||
padding: 5px 10px;
|
||||
border-radius: 6px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.status.ok {
|
||||
background: #d4edda;
|
||||
color: #155724;
|
||||
}
|
||||
|
||||
.status.vencido {
|
||||
background: #f8d7da;
|
||||
color: #721c24;
|
||||
}
|
||||
148
HealthOneProject/assets/css/laudo.css
Normal file
@ -0,0 +1,148 @@
|
||||
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f7f9fb;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: #333;
|
||||
}
|
||||
.brand { display: flex; align-items: center; gap: .6rem; font-weight: 800; letter-spacing: .4px; }
|
||||
.brand .logo { width: 36px; height: 36px; border-radius: 50%; background: #4dd7cf; display: grid; place-items: center; color: #fff; font-weight: 700; box-shadow: 0 6px 14px rgba(29,183,174,.35); }
|
||||
|
||||
.top-bar {
|
||||
background-color: #26bdbd;
|
||||
color: white;
|
||||
text-align: right;
|
||||
padding: 5px 20px;
|
||||
font-size: 13px;
|
||||
border-top-left-radius: 6px;
|
||||
border-top-right-radius: 6px;
|
||||
}
|
||||
|
||||
|
||||
.phone {
|
||||
color: #ff0080;
|
||||
font-size: 14px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
background-color: white;
|
||||
padding: 15px 20px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.nav-links a {
|
||||
text-decoration: none;
|
||||
color: #555;
|
||||
font-weight: 500;
|
||||
padding: 10px 18px;
|
||||
border-radius: 20px;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.nav-links a.active {
|
||||
background: #26bdbd;
|
||||
color: white;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.btn-header {
|
||||
background: none;
|
||||
color: #555;
|
||||
border: none;
|
||||
padding: 10px 18px;
|
||||
border-radius: 20px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-header:hover {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 95%;
|
||||
margin: 30px auto;
|
||||
border-collapse: collapse;
|
||||
background: white;
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
th, td {
|
||||
padding: 12px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
th {
|
||||
background: #00bcd4;
|
||||
color: white;
|
||||
}
|
||||
|
||||
tr:hover {
|
||||
background: #f1f1f1;
|
||||
}
|
||||
|
||||
.status-verde {
|
||||
color: green;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.status-vermelho {
|
||||
color: red;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.acoes button {
|
||||
border: none;
|
||||
padding: 6px 10px;
|
||||
border-radius: 6px;
|
||||
margin-right: 5px;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-editar {
|
||||
background: #2196f3;
|
||||
}
|
||||
|
||||
.btn-revisar {
|
||||
background: #607d8b;
|
||||
}
|
||||
|
||||
.btn-excluir {
|
||||
background: #f44336;
|
||||
}
|
||||
|
||||
.novo-laudo {
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.novo-laudo button {
|
||||
background: #4caf50;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 10px 15px;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.user {
|
||||
margin-right: 800px;
|
||||
}
|
||||
1863
HealthOneProject/assets/css/main.css
Normal file
77
HealthOneProject/assets/css/novo-laudo.css
Normal file
@ -0,0 +1,77 @@
|
||||
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f7f9fb;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #000000;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.editor-toolbar {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.editor-toolbar button {
|
||||
background: #00bcd4;
|
||||
border: none;
|
||||
padding: 8px;
|
||||
margin-right: 5px;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
#laudo-conteudo {
|
||||
width: 100%;
|
||||
height: 250px;
|
||||
border: 1px solid #ccc;
|
||||
padding: 10px;
|
||||
background: white;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.opcoes {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.opcoes input,
|
||||
.opcoes select,
|
||||
.opcoes button {
|
||||
padding: 8px;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.btn-salvar {
|
||||
background: #4caf50;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-cancelar {
|
||||
background: #f44336;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.preview {
|
||||
border: 1px dashed #999;
|
||||
padding: 10px;
|
||||
margin-top: 20px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
81
HealthOneProject/assets/css/revisar-laudo.css
Normal file
@ -0,0 +1,81 @@
|
||||
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f7f9fb;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.dados-paciente {
|
||||
background: #fff;
|
||||
padding: 12px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.dados-paciente p {
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.laudo-box {
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.laudo-box h2 {
|
||||
margin-top: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.acoes {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.acoes button {
|
||||
padding: 10px 15px;
|
||||
margin-right: 10px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.btn-voltar {
|
||||
background: #607d8b;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-imprimir {
|
||||
background: #00bcd4;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-liberar {
|
||||
background: #4caf50;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-excluir {
|
||||
background: #f44336;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Cores do status */
|
||||
.status-verde {
|
||||
color: green;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.status-vermelho {
|
||||
color: red;
|
||||
font-weight: bold;
|
||||
}
|
||||
189
HealthOneProject/assets/css/style-cadastro.css
Normal file
@ -0,0 +1,189 @@
|
||||
:root{
|
||||
/* Paleta clara estilo print */
|
||||
--brand-primary:#22c3b5; /* teal do topo/ações */
|
||||
--brand-primary-600:#18ab9f;
|
||||
--brand-accent:#22c55e; /* verde OK (pode manter) */
|
||||
--bg:#f4f7fb; /* fundo da página claro */
|
||||
--surface:#ffffff; /* cartões/painéis brancos */
|
||||
--surface-2:#ffffff;
|
||||
--text:#0f172a; /* texto principal escuro */
|
||||
--muted:#64748b; /* texto secundário */
|
||||
--border:#e5e9f0; /* linhas divisórias claras */
|
||||
--warning:#f59e0b;
|
||||
--danger:#ef4444;
|
||||
--success:#10b981;
|
||||
--radius:14px;
|
||||
--shadow:0 8px 20px rgba(15,23,42,.08); /* sombra suave */
|
||||
}
|
||||
|
||||
/* fundo geral claro */
|
||||
html,body{height:100%}
|
||||
body{
|
||||
margin:0;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
font:500 14px/1.45 Inter, system-ui, -apple-system, Segoe UI, Roboto, "Helvetica Neue", Arial;
|
||||
}
|
||||
|
||||
*{box-sizing:border-box}
|
||||
html,body{height:100%}
|
||||
body{margin:0;background:linear-gradient(180deg, #0b1220 0%, #0b1220 40%, #0a0f1a 100%);color:var(--text);font:500 14px/1.4 Inter, system-ui, -apple-system, Segoe UI, Roboto, "Helvetica Neue", Arial}
|
||||
|
||||
/* Header */
|
||||
/* Header: faixa translúcida teal com blur (como no print) */
|
||||
.app-header{
|
||||
display:flex;align-items:center;justify-content:space-between;
|
||||
padding:14px 22px;
|
||||
border-bottom:1px solid var(--border);
|
||||
position:sticky;top:0;z-index:40;
|
||||
background:linear-gradient(0deg, rgba(45, 171, 209, 0.92), rgba(34,195,181,.92));
|
||||
backdrop-filter:blur(6px);
|
||||
}
|
||||
/* Marca compacta */
|
||||
.app-brand{display:flex;gap:10px;align-items:center}
|
||||
.brand-mark{width:32px;height:32px;border-radius:999px;
|
||||
background:#000000; box-shadow:0 2px 6px rgba(0,0,0,.08);}
|
||||
.brand-title{font-weight:800;letter-spacing:.2px;color:#000000}
|
||||
|
||||
/* Subtítulo claro */
|
||||
.app-brand .muted{color:rgba(0, 0, 0, 0.9)}
|
||||
|
||||
/* Navegação tipo “pill” */
|
||||
.top-nav{display:flex;gap:8px;align-items:center}
|
||||
.top-nav a{
|
||||
display:inline-flex;align-items:center;gap:8px;
|
||||
padding:10px 14px;border-radius:999px;
|
||||
background:transparent;border:1px solid transparent;
|
||||
text-decoration:none;color:#000000;font-weight:700;opacity:.95;
|
||||
transition:.15s ease;
|
||||
}
|
||||
.top-nav a:hover{opacity:1; background:rgba(255,255,255,.12)}
|
||||
.top-nav a.active{
|
||||
background:#ffffff; color:#0f172a; border-color:#ffffff;
|
||||
box-shadow:0 8px 22px rgba(15,23,42,.12);
|
||||
}
|
||||
.top-nav .pill{
|
||||
font-size:11px;padding:2px 8px;border-radius:999px;
|
||||
background:rgba(15,23,42,.08); color:#0f172a;border:1px solid rgba(15,23,42,.06)
|
||||
}
|
||||
.brand-mark{width:10px;height:10px;border-radius:10px;}
|
||||
.brand-title{font-weight:800;letter-spacing:.5px}
|
||||
|
||||
/* cartão branco com borda clarinha e sombra suave */
|
||||
.card{
|
||||
background:var(--surface);
|
||||
border:1px solid var(--border);
|
||||
border-radius:18px;
|
||||
box-shadow:var(--shadow);
|
||||
overflow:hidden;
|
||||
}
|
||||
.card-header{
|
||||
display:flex;flex-wrap:wrap;gap:10px;align-items:center;justify-content:space-between;
|
||||
padding:18px 20px;border-bottom:1px solid var(--border); background:#fff;
|
||||
}
|
||||
.card-title{font-size:18px;font-weight:800;color:#0f172a}
|
||||
.card-actions{display:flex;gap:10px}
|
||||
|
||||
/* botões em pill com sombra sutil */
|
||||
.btn{
|
||||
appearance:none;border:1px solid transparent;
|
||||
background:var(--brand-primary);color:#fff;
|
||||
padding:10px 16px;border-radius:999px;font-weight:800;cursor:pointer;
|
||||
transition:.18s ease; box-shadow:0 6px 16px rgba(34,195,181,.26);
|
||||
}
|
||||
.btn:hover{background:var(--brand-primary-600); transform:translateY(-1px)}
|
||||
.btn.secondary{
|
||||
background:#ffffff;border-color:var(--border);color:#0f172a;
|
||||
box-shadow:0 2px 8px rgba(15,23,42,.06);
|
||||
}
|
||||
.btn.secondary:hover{border-color:#dfe5ee}
|
||||
|
||||
/* seções com cabeçalho claro (sem degradê escuro) */
|
||||
.section{border:1px solid var(--border);border-radius:14px;overflow:hidden;background:#fff}
|
||||
.section-header{
|
||||
display:flex;align-items:center;gap:12px;justify-content:space-between;
|
||||
padding:14px 16px;background:#f8fafc;border-bottom:1px solid var(--border)
|
||||
}
|
||||
.section-title{font-weight:800;color:#0f172a}
|
||||
|
||||
.grid{display:grid;gap:12px}
|
||||
.grid-cols-2{grid-template-columns:repeat(2, minmax(0,1fr))}
|
||||
.grid-cols-3{grid-template-columns:repeat(3, minmax(0,1fr))}
|
||||
.grid-cols-4{grid-template-columns:repeat(4, minmax(0,1fr))}
|
||||
@media (max-width:900px){.grid-cols-4,.grid-cols-3{grid-template-columns:repeat(2, minmax(0,1fr))}}
|
||||
@media (max-width:640px){.grid-cols-4,.grid-cols-3,.grid-cols-2{grid-template-columns:1fr}}
|
||||
|
||||
.field{display:flex;flex-direction:column;gap:6px}
|
||||
/* campos: fundo branco, borda clara, foco teal */
|
||||
.field label{font-size:12px;color:#64748b}
|
||||
.field input[type="text"],
|
||||
.field input[type="email"],
|
||||
.field input[type="date"],
|
||||
.field input[type="tel"],
|
||||
.field input[type="number"],
|
||||
.field select,
|
||||
.field textarea{
|
||||
background:#ffffff;border:1px solid var(--border);color:#0f172a;
|
||||
padding:10px 12px;border-radius:12px;outline:none;transition:border-color .15s, box-shadow .15s;
|
||||
}
|
||||
.field textarea{min-height:120px;resize:vertical}
|
||||
.field input:focus,.field select:focus,.field textarea:focus{
|
||||
border-color:var(--brand-primary);
|
||||
box-shadow:0 0 0 3px rgba(34,195,181,.18);
|
||||
}
|
||||
|
||||
.inline{display:flex;gap:12px;align-items:center;flex-wrap:wrap}
|
||||
.muted{color:var(--muted)}
|
||||
|
||||
.avatar-uploader{display:flex;gap:16px;align-items:center}
|
||||
/* avatar com borda pontilhada bem clara */
|
||||
.avatar{width:88px;height:88px;border-radius:16px;background:#fafbff;border:1px dashed #dfe5ee}
|
||||
.avatar img{width:100%;height:100%;object-fit:cover}
|
||||
|
||||
.radio-group{display:flex;gap:12px;flex-wrap:wrap}
|
||||
/* radios / toggles mantidos; só o toggle ganha leve borda clara */
|
||||
.toggle{background:#f1f5f9;border:1px solid #dfe5ee}
|
||||
.toggle::after{background:#ffffff}
|
||||
.toggle.active{background:var(--brand-primary)}
|
||||
.toggle.active::after{left:25px;background:white}
|
||||
|
||||
details.section summary{list-style:none;cursor:pointer}
|
||||
details.section[open] .section-header{border-bottom-color:transparent}
|
||||
|
||||
/* attachments: divisórias clarinhas */
|
||||
.attachments{border-top:1px dashed #e8edf3}
|
||||
.attach-row{border-bottom:1px dashed #eef2f7}
|
||||
|
||||
.error{color:var(--danger);font-size:12px}
|
||||
.hint{font-size:12px;color:var(--muted)}
|
||||
|
||||
.toast{position:fixed;right:16px;bottom:16px;background:#0b1220;border:1px solid var(--border);padding:12px 14px;border-radius:10px;box-shadow:var(--shadow);opacity:0;transform:translateY(10px);transition:.25s}
|
||||
.toast.show{opacity:1;transform:translateY(0)}
|
||||
|
||||
.preview{background:rgba(255,255,255,.02);border:1px dashed var(--border);border-radius:12px;padding:12px;font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;font-size:12px;white-space:pre-wrap}
|
||||
|
||||
/* Se NÃO tiver CSS externo, você pode colar aqui um básico ou reutilizar o seu de antes */
|
||||
/* Coloquei apenas pequenas classes usadas pelo toast/preview para não quebrar */
|
||||
.muted{color:#64748b}
|
||||
.error{color:#ef4444;font-size:12px}
|
||||
.hint{font-size:12px;color:#64748b}
|
||||
.toast{position:fixed;right:16px;bottom:16px;background:#fff;border:1px solid #e5e7eb;padding:12px 14px;border-radius:10px;box-shadow:0 8px 20px rgba(0,0,0,.12);opacity:0;transform:translateY(10px);transition:.25s;color:#0f172a}
|
||||
.toast.show{opacity:1;transform:translateY(0)}
|
||||
.avatar{width:88px;height:88px;border-radius:12px;border:1px dashed #dfe5ee;display:grid;place-items:center;overflow:hidden}
|
||||
.avatar img{width:100%;height:100%;object-fit:cover}
|
||||
.toggle{position:relative;width:50px;height:28px;background:#f1f5f9;border:1px solid #dfe5ee;border-radius:999px;cursor:pointer}
|
||||
.toggle::after{content:"";position:absolute;top:3px;left:3px;width:22px;height:22px;border-radius:50%;background:#fff;transition:.2s}
|
||||
.toggle.active{background:#22c3b5;border-color:transparent}
|
||||
.toggle.active::after{left:25px}
|
||||
.preview{background:#fff;border:1px dashed #e5e7eb;border-radius:12px;padding:12px;font-family:ui-monospace,monospace;font-size:12px;white-space:pre-wrap}
|
||||
.btn{appearance:none;border:1px solid transparent;background:#22c3b5;color:#fff;padding:10px 14px;border-radius:999px;font-weight:700;cursor:pointer}
|
||||
.btn.secondary{background:#fff;border-color:#e5e7eb;color:#0f172a}
|
||||
.top-nav a.active{background:#22c3b5;color:#fff;border-radius:999px;padding:6px 10px}
|
||||
.section{border:1px solid #e5e7eb;border-radius:12px;margin:12px 0}
|
||||
.section-header{display:flex;align-items:center;justify-content:space-between;padding:12px 14px;border-bottom:1px solid #e5e7eb;background:#f8fafc}
|
||||
.grid{display:grid;gap:12px}
|
||||
.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}
|
||||
@media (max-width:900px){.grid-cols-4{grid-template-columns:repeat(2,minmax(0,1fr))}}
|
||||
@media (max-width:640px){.grid-cols-4{grid-template-columns:1fr}}
|
||||
.field{display:flex;flex-direction:column;gap:6px}
|
||||
.field input,.field select,.field textarea{padding:10px 12px;border:1px solid #e5e7eb;border-radius:10px}
|
||||
BIN
HealthOneProject/assets/img/Logo do HealthOne.png
Normal file
|
After Width: | Height: | Size: 136 KiB |
BIN
HealthOneProject/assets/img/about.jpg
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
HealthOneProject/assets/img/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
BIN
HealthOneProject/assets/img/departments-1.jpg
Normal file
|
After Width: | Height: | Size: 63 KiB |
BIN
HealthOneProject/assets/img/departments-2.jpg
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
HealthOneProject/assets/img/departments-3.jpg
Normal file
|
After Width: | Height: | Size: 57 KiB |
BIN
HealthOneProject/assets/img/departments-4.jpg
Normal file
|
After Width: | Height: | Size: 55 KiB |
BIN
HealthOneProject/assets/img/departments-5.jpg
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
HealthOneProject/assets/img/doctors/doctors-1.jpg
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
HealthOneProject/assets/img/doctors/doctors-2.jpg
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
HealthOneProject/assets/img/doctors/doctors-3.jpg
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
HealthOneProject/assets/img/doctors/doctors-4.jpg
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
HealthOneProject/assets/img/favicon.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
HealthOneProject/assets/img/features.jpg
Normal file
|
After Width: | Height: | Size: 57 KiB |
BIN
HealthOneProject/assets/img/hero-carousel/hero-carousel-1.jpg
Normal file
|
After Width: | Height: | Size: 247 KiB |
BIN
HealthOneProject/assets/img/hero-carousel/hero-carousel-2.jpg
Normal file
|
After Width: | Height: | Size: 134 KiB |
BIN
HealthOneProject/assets/img/hero-carousel/hero-carousel-3.jpg
Normal file
|
After Width: | Height: | Size: 191 KiB |
BIN
HealthOneProject/assets/img/testimonials/testimonials-1.jpg
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
HealthOneProject/assets/img/testimonials/testimonials-2.jpg
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
HealthOneProject/assets/img/testimonials/testimonials-3.jpg
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
HealthOneProject/assets/img/testimonials/testimonials-4.jpg
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
HealthOneProject/assets/img/testimonials/testimonials-5.jpg
Normal file
|
After Width: | Height: | Size: 22 KiB |
22
HealthOneProject/assets/js/apiClient.js
Normal file
@ -0,0 +1,22 @@
|
||||
// /js/apiClient.js
|
||||
export const BASE_URL = 'https://mock.apidog.com/m1/1053378-0-default';
|
||||
|
||||
export async function api(path, { method='GET', data, token } = {}) {
|
||||
const headers = { 'Content-Type': 'application/json' };
|
||||
if (token) headers.Authorization = `Bearer ${token}`; // use se ativar auth no Apidog
|
||||
|
||||
const res = await fetch(`${BASE_URL}${path}`, {
|
||||
method,
|
||||
headers,
|
||||
body: data ? JSON.stringify(data) : undefined,
|
||||
});
|
||||
|
||||
const text = await res.text();
|
||||
let payload; try { payload = text ? JSON.parse(text) : null; } catch { payload = text; }
|
||||
|
||||
if (!res.ok) {
|
||||
const msg = (payload && (payload.message || payload.error)) || res.statusText;
|
||||
throw new Error(`API ${method} ${path} falhou: ${msg}`);
|
||||
}
|
||||
return payload; // atenção: endpoints retornam { success, data, ... }
|
||||
}
|
||||
340
HealthOneProject/assets/js/cadastro.js
Normal file
@ -0,0 +1,340 @@
|
||||
|
||||
/* ========================= LocalStorage utils ========================= */
|
||||
const LS_KEY_PACIENTES = 'healthone.pacientes';
|
||||
function loadPacientes(){ try { return JSON.parse(localStorage.getItem(LS_KEY_PACIENTES) || '[]'); } catch { return []; } }
|
||||
function setPacientes(arr){ localStorage.setItem(LS_KEY_PACIENTES, JSON.stringify(arr)); }
|
||||
function ensureId(p){ p.id = p.id || (crypto?.randomUUID?.() || String(Date.now()+Math.floor(Math.random()*1000))); return p; }
|
||||
function salvarPaciente(paciente){
|
||||
ensureId(paciente);
|
||||
const arr = loadPacientes();
|
||||
const idx = arr.findIndex(x => String(x.id) === String(paciente.id));
|
||||
if (idx >= 0) arr[idx] = paciente; else arr.push(paciente);
|
||||
setPacientes(arr);
|
||||
}
|
||||
|
||||
/* ========================= Helpers ========================= */
|
||||
// datas: aceita DD/MM/YYYY, D/M/YYYY, YYYY-MM-DD, YYYY/M/D
|
||||
function parseDateSmart(v){
|
||||
if (!v) return null;
|
||||
if (v instanceof Date) return v;
|
||||
const s = String(v).trim();
|
||||
|
||||
let m = s.match(/^(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{2,4})$/); // DD/MM/YYYY
|
||||
if (m){
|
||||
let dd = +m[1], mm = +m[2], yyyy = +m[3];
|
||||
if (yyyy < 100) yyyy += 2000;
|
||||
const d = new Date(Date.UTC(yyyy, mm-1, dd));
|
||||
if (d.getUTCFullYear() === yyyy && d.getUTCMonth() === mm-1 && d.getUTCDate() === dd) return d;
|
||||
return null;
|
||||
}
|
||||
m = s.match(/^(\d{4})[\/\-](\d{1,2})[\/\-](\d{1,2})$/); // YYYY-MM-DD
|
||||
if (m){
|
||||
const yyyy = +m[1], mm = +m[2], dd = +m[3];
|
||||
const d = new Date(Date.UTC(yyyy, mm-1, dd));
|
||||
if (d.getUTCFullYear() === yyyy && d.getUTCMonth() === mm-1 && d.getUTCDate() === dd) return d;
|
||||
return null;
|
||||
}
|
||||
const d = new Date(s);
|
||||
return isNaN(d) ? null : d;
|
||||
}
|
||||
function toISODate(v){ // 'YYYY-MM-DD' p/ <input type="date">
|
||||
const d = parseDateSmart(v);
|
||||
if (!d) return '';
|
||||
const yyyy = d.getUTCFullYear();
|
||||
const mm = String(d.getUTCMonth()+1).padStart(2,'0');
|
||||
const dd = String(d.getUTCDate()).padStart(2,'0');
|
||||
return `${yyyy}-${mm}-${dd}`;
|
||||
}
|
||||
|
||||
const $ = (s,p=document)=>p.querySelector(s);
|
||||
const $$ = (s,p=document)=>[...p.querySelectorAll(s)];
|
||||
function onlyDigits(v){ return (v||'').replace(/\D+/g,''); }
|
||||
function maskCPF(v){ v = onlyDigits(v).slice(0,11); return v.replace(/(\d{3})(\d)/,'$1.$2').replace(/(\d{3})(\d)/,'$1.$2').replace(/(\d{3})(\d{1,2})$/,'$1-$2'); }
|
||||
function maskCEP(v){ v = onlyDigits(v).slice(0,8); return v.replace(/(\d{5})(\d)/,'$1-$2'); }
|
||||
function maskPhoneBRIntl(v){
|
||||
v = onlyDigits(v);
|
||||
if(!v.startsWith('55')) v = '55'+v;
|
||||
v = v.slice(0,13);
|
||||
const ddi=v.slice(0,2), ddd=v.slice(2,4), rest=v.slice(4);
|
||||
if(rest.length>9) return `+${ddi} (${ddd}) ${rest.slice(0,5)}-${rest.slice(5,9)}`;
|
||||
if(rest.length>4) return `+${ddi} (${ddd}) ${rest.slice(0,4)}-${rest.slice(4,8)}`;
|
||||
if(ddd) return `+${ddi} (${ddd}) ${rest}`;
|
||||
return `+${ddi}`;
|
||||
}
|
||||
function isValidCPF(raw){
|
||||
const s = onlyDigits(raw);
|
||||
if(s.length!==11) return false;
|
||||
if(/^([0-9])\1+$/.test(s)) return false;
|
||||
let sum=0; for(let i=0;i<9;i++) sum+=parseInt(s[i])*(10-i);
|
||||
let d1=(sum*10)%11; if(d1===10) d1=0; if(d1!==parseInt(s[9])) return false;
|
||||
sum=0; for(let i=0;i<10;i++) sum+=parseInt(s[i])*(11-i);
|
||||
let d2=(sum*10)%11; if(d2===10) d2=0; if(d2!==parseInt(s[10])) return false;
|
||||
return true;
|
||||
}
|
||||
function toast(msg, ok=true){
|
||||
const t = $('#toast'); t.textContent = msg;
|
||||
t.style.borderColor = ok? '#10b981':'#ef4444';
|
||||
t.classList.add('show'); setTimeout(()=> t.classList.remove('show'), 2200);
|
||||
}
|
||||
|
||||
/* ========================= Upload de avatar ========================= */
|
||||
const photoInput = $('#photo');
|
||||
const avatar = $('#avatarPreview');
|
||||
$('#btnUpload').addEventListener('click', ()=> photoInput.click());
|
||||
photoInput.addEventListener('change', ()=>{
|
||||
const f = photoInput.files?.[0]; if(!f) return;
|
||||
const reader = new FileReader();
|
||||
reader.onload = e => { avatar.innerHTML = `<img alt="Foto do paciente" src="${e.target.result}"/>`; };
|
||||
reader.readAsDataURL(f);
|
||||
});
|
||||
|
||||
/* ========================= Interações de campos ========================= */
|
||||
const rnToggle = $('#rnToggle');
|
||||
rnToggle?.addEventListener('click', ()=> rnToggle.classList.toggle('active'));
|
||||
rnToggle?.addEventListener('keydown', (e)=>{ if(e.key==='Enter'||e.key===' '){ e.preventDefault(); rnToggle.click(); } });
|
||||
|
||||
const docTipo = $('#docTipo');
|
||||
const docNumero = $('#docNumero');
|
||||
docTipo.addEventListener('change', ()=>{
|
||||
docNumero.disabled = !docTipo.value;
|
||||
docNumero.placeholder = docTipo.value ? `Número do ${docTipo.value}` : 'Preencha após selecionar o tipo';
|
||||
});
|
||||
|
||||
const temResp = $('#temResponsavel');
|
||||
const respNome = $('#responsavel');
|
||||
const respCpf = $('#cpfResponsavel');
|
||||
temResp.addEventListener('change', ()=>{
|
||||
const on = temResp.value==='sim';
|
||||
respNome.disabled = respCpf.disabled = !on;
|
||||
if(!on){ respNome.value=''; respCpf.value=''; }
|
||||
});
|
||||
|
||||
// máscaras
|
||||
const cpf = $('#cpf'); cpf.addEventListener('input', ()=> cpf.value = maskCPF(cpf.value));
|
||||
const cpfResp = $('#cpfResponsavel'); cpfResp.addEventListener('input', ()=> cpfResp.value = maskCPF(cpfResp.value));
|
||||
const celular = $('#celular'); const tel1=$('#tel1'); const tel2=$('#tel2');
|
||||
;[celular,tel1,tel2].forEach(el=> el.addEventListener('input', ()=> el.value = maskPhoneBRIntl(el.value)));
|
||||
const cep = $('#cep'); cep.addEventListener('input', ()=> cep.value = maskCEP(cep.value));
|
||||
|
||||
// validações
|
||||
const email = $('#email');
|
||||
email.addEventListener('blur', ()=> $('#err-email').textContent = (email.value && !email.checkValidity()) ? 'Formato de e-mail inválido.' : '');
|
||||
cpf.addEventListener('blur', ()=> $('#err-cpf').textContent = (cpf.value && !isValidCPF(cpf.value)) ? 'CPF inválido.' : '');
|
||||
|
||||
// ViaCEP
|
||||
async function buscarCEP(v){
|
||||
const s = onlyDigits(v); if(s.length!==8) return;
|
||||
try{
|
||||
const res = await fetch(`https://viacep.com.br/ws/${s}/json/`);
|
||||
const data = await res.json();
|
||||
if(data.erro){ $('#err-cep').textContent='CEP não encontrado.'; return; }
|
||||
$('#err-cep').textContent='';
|
||||
$('#logradouro').value = data.logradouro || '';
|
||||
$('#bairro').value = data.bairro || '';
|
||||
$('#cidade').value = data.localidade || '';
|
||||
$('#uf').value = data.uf || '';
|
||||
}catch{ $('#err-cep').textContent='Falha ao consultar CEP.'; }
|
||||
}
|
||||
cep.addEventListener('blur', ()=> buscarCEP(cep.value));
|
||||
|
||||
/* ========================= Coletar dados / validar ========================= */
|
||||
const form = $('#patientForm');
|
||||
function getFormData(){
|
||||
return {
|
||||
foto: photoInput.files?.[0]?.name || null,
|
||||
nome: $('#nome').value.trim(),
|
||||
nomeSocial: $('#nomeSocial').value.trim(),
|
||||
cpf: $('#cpf').value.trim(),
|
||||
rg: $('#rg').value.trim(),
|
||||
doc:{ tipo: $('#docTipo').value, numero: $('#docNumero').value.trim() },
|
||||
sexo: (form.querySelector('input[name="sexo"]:checked')||{}).value || '',
|
||||
nasc: $('#nasc').value, // <input type="date"> fornece YYYY-MM-DD
|
||||
raca: $('#raca').value,
|
||||
etnia: $('#etnia').value.trim(),
|
||||
naturalidade: $('#naturalidade').value.trim(),
|
||||
nacionalidade: $('#nacionalidade').value,
|
||||
profissao: $('#profissao').value.trim(),
|
||||
estadoCivil: $('#estadoCivil').value,
|
||||
filiacao:{ mae: $('#mae').value.trim(), profMae: $('#profMae').value.trim(), pai: $('#pai').value.trim(), profPai: $('#profPai').value.trim() },
|
||||
responsavel:{ ativo: $('#temResponsavel').value==='sim', nome: $('#responsavel').value.trim(), cpf: $('#cpfResponsavel').value.trim() },
|
||||
esposo: $('#esposo').value.trim(),
|
||||
rnGuia: rnToggle?.classList.contains('active') || false,
|
||||
codigoLegado: $('#codigoLegado').value.trim(),
|
||||
obs: $('#obs').value.trim(),
|
||||
contato:{ email: $('#email').value.trim(), celular: $('#celular').value.trim(), tel1: $('#tel1').value.trim(), tel2: $('#tel2').value.trim() },
|
||||
endereco:{ cep: $('#cep').value.trim(), logradouro: $('#logradouro').value.trim(), numero: $('#numero').value.trim(), complemento: $('#complemento').value.trim(), bairro: $('#bairro').value.trim(), cidade: $('#cidade').value.trim(), uf: $('#uf').value.trim(), referencia: $('#referencia').value.trim() },
|
||||
|
||||
// ✅ NOVOS CAMPOS — salva no formato ISO (YYYY-MM-DD)
|
||||
ultimaConsulta: toISODate($('#ultimaConsulta').value),
|
||||
proximaConsulta: toISODate($('#proximaConsulta').value),
|
||||
};
|
||||
}
|
||||
function validateBeforeSave(data){
|
||||
let ok=true;
|
||||
if(!data.nome){ $('#err-nome').textContent='Informe o nome.'; ok=false; } else { $('#err-nome').textContent=''; }
|
||||
if(data.cpf && !isValidCPF(data.cpf)){ $('#err-cpf').textContent='CPF inválido.'; ok=false; } else { $('#err-cpf').textContent=''; }
|
||||
if(data.contato.email && !email.checkValidity()){ $('#err-email').textContent='Formato de e-mail inválido.'; ok=false; } else { $('#err-email').textContent=''; }
|
||||
if(data.responsavel.ativo){
|
||||
if(!data.responsavel.nome){ ok=false; toast('Informe o nome do responsável.', false); }
|
||||
if(data.responsavel.cpf && !isValidCPF(data.responsavel.cpf)){ ok=false; toast('CPF do responsável inválido.', false); }
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
function renderPreview(obj){
|
||||
const el = document.querySelector('#jsonPreview');
|
||||
if (!el) return;
|
||||
el.textContent = JSON.stringify(obj, null, 2);
|
||||
}
|
||||
|
||||
/* ========================= Edição via ?id= ========================= */
|
||||
let editingId = null;
|
||||
(function hydrateIfEditing(){
|
||||
const params = new URLSearchParams(location.search);
|
||||
const idParam = params.get('id');
|
||||
if(!idParam) return; // sem id = novo
|
||||
const id = String(idParam); // mantém string
|
||||
const lista = loadPacientes();
|
||||
const p = lista.find(x => String(x.id) === id);
|
||||
if(!p) return;
|
||||
|
||||
editingId = id;
|
||||
|
||||
// Preenche campos
|
||||
$('#nome').value = p.nome||'';
|
||||
$('#nomeSocial').value = p.nomeSocial||'';
|
||||
$('#cpf').value = p.cpf||'';
|
||||
$('#rg').value = p.rg||'';
|
||||
$('#docTipo').value = p.doc?.tipo||'';
|
||||
$('#docNumero').value = p.doc?.numero||''; $('#docNumero').disabled = !p.doc?.tipo;
|
||||
if(p.sexo){ const el = document.querySelector(`input[name="sexo"][value="${p.sexo}"]`); el && (el.checked=true); }
|
||||
$('#nasc').value = toISODate(p.nasc || p.dataNascimento) || '';
|
||||
$('#raca').value = p.raca||'';
|
||||
$('#etnia').value = p.etnia||'';
|
||||
$('#naturalidade').value = p.naturalidade||'';
|
||||
$('#nacionalidade').value = p.nacionalidade||'';
|
||||
$('#profissao').value = p.profissao||'';
|
||||
$('#estadoCivil').value = p.estadoCivil||'';
|
||||
$('#mae').value = p.filiacao?.mae||'';
|
||||
$('#profMae').value = p.filiacao?.profMae||'';
|
||||
$('#pai').value = p.filiacao?.pai||'';
|
||||
$('#profPai').value = p.filiacao?.profPai||'';
|
||||
$('#temResponsavel').value = p.responsavel?.ativo ? 'sim' : 'nao';
|
||||
const on = p.responsavel?.ativo; $('#responsavel').disabled = $('#cpfResponsavel').disabled = !on;
|
||||
$('#responsavel').value = p.responsavel?.nome||'';
|
||||
$('#cpfResponsavel').value = p.responsavel?.cpf||'';
|
||||
if(p.rnGuia) $('#rnToggle')?.classList.add('active');
|
||||
$('#codigoLegado').value = p.codigoLegado||'';
|
||||
$('#obs').value = p.obs||'';
|
||||
$('#email').value = p.contato?.email||'';
|
||||
$('#celular').value = p.contato?.celular||'';
|
||||
$('#tel1').value = p.contato?.tel1||'';
|
||||
$('#tel2').value = p.contato?.tel2||'';
|
||||
$('#cep').value = p.endereco?.cep||'';
|
||||
$('#logradouro').value = p.endereco?.logradouro||'';
|
||||
$('#numero').value = p.endereco?.numero||'';
|
||||
$('#complemento').value = p.endereco?.complemento||'';
|
||||
$('#bairro').value = p.endereco?.bairro||'';
|
||||
$('#cidade').value = p.endereco?.cidade||'';
|
||||
$('#uf').value = p.endereco?.uf||'';
|
||||
$('#referencia').value = p.endereco?.referencia||'';
|
||||
|
||||
// ✅ Consultas (pré-preencher)
|
||||
$('#ultimaConsulta').value = toISODate(p.ultimaConsulta ?? p.ultima_consulta ?? p.ultConsulta) || '';
|
||||
$('#proximaConsulta').value = toISODate(p.proximaConsulta ?? p.proxima_consulta ?? p.proxConsulta) || '';
|
||||
|
||||
renderPreview(p);
|
||||
})();
|
||||
|
||||
/* ========================= Salvar / Cancelar ========================= */
|
||||
$('#btnSave').addEventListener('click', ()=>{
|
||||
const paciente = getFormData();
|
||||
if(!validateBeforeSave(paciente)) return;
|
||||
|
||||
if (editingId){
|
||||
paciente.id = editingId; // mantém o mesmo id (update)
|
||||
}
|
||||
salvarPaciente(paciente); // cria ou atualiza
|
||||
|
||||
toast(editingId ? 'Paciente atualizado!' : 'Paciente salvo!', true);
|
||||
renderPreview(paciente);
|
||||
setTimeout(()=> location.href = 'crud-pacientes.html', 500);
|
||||
});
|
||||
|
||||
$('#btnCancel').addEventListener('click', ()=>{
|
||||
if(confirm('Cancelar e voltar à lista?')){
|
||||
form.reset(); avatar.innerHTML = '<span class="muted">Sem foto</span>'; renderPreview({});
|
||||
location.href = 'crud-pacientes.html';
|
||||
}
|
||||
});
|
||||
|
||||
/* ========================= UI ========================= */
|
||||
(function highlightActive(){
|
||||
const cur = 'cadastro';
|
||||
document.querySelectorAll('.top-nav a').forEach(a=>{
|
||||
if(a.dataset.page===cur) a.classList.add('active');
|
||||
});
|
||||
})();
|
||||
|
||||
/* ========================= Anexos (mock local) ========================= */
|
||||
const anexosLista = $('#anexosLista');
|
||||
const anexosInput = $('#anexosInput');
|
||||
$('#btnAddAnexos').addEventListener('click', ()=> anexosInput.click());
|
||||
anexosInput.addEventListener('change', ()=>{
|
||||
[...anexosInput.files].forEach(f=> addAnexo(f));
|
||||
anexosInput.value='';
|
||||
});
|
||||
function addAnexo(file){
|
||||
const row = document.createElement('div');
|
||||
row.style.cssText='display:flex;justify-content:space-between;align-items:center;padding:10px 0;border-bottom:1px dashed #eef2f7';
|
||||
const left = document.createElement('div');
|
||||
left.innerHTML = `<strong>${file.name}</strong><div class="muted" style="font-size:12px">${new Date().toLocaleString()}</div>`;
|
||||
const right = document.createElement('div');
|
||||
const btn = document.createElement('button');
|
||||
btn.className='btn secondary'; btn.type='button'; btn.textContent='Excluir';
|
||||
btn.addEventListener('click', ()=> row.remove());
|
||||
right.appendChild(btn);
|
||||
row.append(left, right);
|
||||
anexosLista.appendChild(row);
|
||||
}
|
||||
|
||||
// /js/cadastro.js
|
||||
import { getPaciente, updatePaciente, createPaciente } from './pacientesService.js';
|
||||
|
||||
const $form = document.querySelector('#patientForm');
|
||||
const params = new URLSearchParams(location.search);
|
||||
const id = params.get('id');
|
||||
|
||||
function fillForm(obj = {}) {
|
||||
Object.entries(obj).forEach(([k, v]) => {
|
||||
const el = $form.elements.namedItem(k);
|
||||
if (el) el.value = v ?? '';
|
||||
});
|
||||
}
|
||||
|
||||
async function load() {
|
||||
if (!id) return;
|
||||
try {
|
||||
const p = await getPaciente(id);
|
||||
if (!p) return alert('Paciente não encontrado');
|
||||
fillForm(p);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
alert('Erro ao carregar paciente');
|
||||
}
|
||||
}
|
||||
|
||||
$form.addEventListener('submit', async (ev) => {
|
||||
ev.preventDefault();
|
||||
const data = Object.fromEntries(new FormData($form));
|
||||
try {
|
||||
if (id) await updatePaciente(id, data);
|
||||
else await createPaciente(data);
|
||||
alert('Salvo com sucesso!');
|
||||
location.href = 'crud-pacientes.html';
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
alert(`Erro ao salvar: ${e.message}`);
|
||||
}
|
||||
});
|
||||
|
||||
load();
|
||||
368
HealthOneProject/assets/js/crud-pacientes.js
Normal file
@ -0,0 +1,368 @@
|
||||
// /js/crud-pacientes.js
|
||||
/* ========================= Imports (API) ========================= */
|
||||
import { listPacientes, deletePaciente, createPaciente, getPaciente } from './pacientesService.js';
|
||||
|
||||
/* ========================= Seletores / Estado ========================= */
|
||||
const SEL = {
|
||||
tbody: '#tbody',
|
||||
pager: '#pager',
|
||||
search: '#q',
|
||||
count: '#countLabel',
|
||||
btnNew: '#btnNew',
|
||||
topNavLinks: '.top-nav a'
|
||||
};
|
||||
|
||||
const $ = (s, p=document)=>p.querySelector(s);
|
||||
const $$ = (s, p=document)=>[...p.querySelectorAll(s)];
|
||||
const byId = (id)=>document.getElementById(id);
|
||||
|
||||
const tbody = $(SEL.tbody);
|
||||
const pager = $(SEL.pager);
|
||||
const q = $(SEL.search);
|
||||
const countLabel = $(SEL.count);
|
||||
const btnNew = $(SEL.btnNew);
|
||||
|
||||
let pacientes = []; // cache do que veio da API (normalizado)
|
||||
let filtro = '';
|
||||
let page = 1;
|
||||
const perPage = 10;
|
||||
|
||||
/* ========================= Helpers (strings/datas) ========================= */
|
||||
function normalize(s){ return (s||'').toString().toLowerCase(); }
|
||||
function fmtIndex(n){ return String(n).padStart(3,'0'); }
|
||||
|
||||
function parseDateSmart(v){
|
||||
if (!v) return null;
|
||||
if (v instanceof Date) return v;
|
||||
const s = String(v).trim();
|
||||
|
||||
let m = s.match(/^(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{2,4})$/); // DD/MM/YYYY
|
||||
if (m) {
|
||||
let dd = +m[1], mm = +m[2], yyyy = +m[3];
|
||||
if (yyyy < 100) yyyy += 2000;
|
||||
const d = new Date(Date.UTC(yyyy, mm - 1, dd));
|
||||
if (d.getUTCFullYear() === yyyy && d.getUTCMonth() === mm - 1 && d.getUTCDate() === dd) return d;
|
||||
return null;
|
||||
}
|
||||
m = s.match(/^(\d{4})[\/\-](\d{1,2})[\/\-](\d{1,2})$/); // YYYY-MM-DD
|
||||
if (m) {
|
||||
const yyyy = +m[1], mm = +m[2], dd = +m[3];
|
||||
const d = new Date(Date.UTC(yyyy, mm - 1, dd));
|
||||
if (d.getUTCFullYear() === yyyy && d.getUTCMonth() === mm - 1 && d.getUTCDate() === dd) return d;
|
||||
return null;
|
||||
}
|
||||
const d = new Date(s);
|
||||
return isNaN(d) ? null : d;
|
||||
}
|
||||
function formatData(input){
|
||||
const d = parseDateSmart(input);
|
||||
return d
|
||||
? new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()))
|
||||
.toLocaleDateString('pt-BR', { timeZone: 'UTC' })
|
||||
: '—';
|
||||
}
|
||||
function calcIdade(input){
|
||||
const d = parseDateSmart(input);
|
||||
if (!d) return null;
|
||||
const hoje = new Date();
|
||||
let idade = hoje.getUTCFullYear() - d.getUTCFullYear();
|
||||
const m = hoje.getUTCMonth() - d.getUTCMonth();
|
||||
if (m < 0 || (m === 0 && hoje.getUTCDate() < d.getUTCDate())) idade--;
|
||||
return idade;
|
||||
}
|
||||
function normalizaGenero(g){
|
||||
if (!g) return null;
|
||||
const s = String(g).trim().toLowerCase();
|
||||
if (['m','masc','masculino','homem'].includes(s)) return 'Masculino';
|
||||
if (['f','fem','feminino','mulher'].includes(s)) return 'Feminino';
|
||||
return String(g);
|
||||
}
|
||||
function formatCPF(v){
|
||||
if(!v) return "—";
|
||||
const only = String(v).replace(/\D/g,'').padStart(11,'0').slice(-11);
|
||||
return only.replace(/(\d{3})(\d{3})(\d{3})(\d{2})/,'$1.$2.$3-$4');
|
||||
}
|
||||
function iniciais(nome){
|
||||
if(!nome) return "PT";
|
||||
return nome.split(/\s+/).slice(0,2).map(p=>p[0]).join('').toUpperCase();
|
||||
}
|
||||
|
||||
/* ========================= Normalização API -> View ========================= */
|
||||
function fromApi(p) {
|
||||
// garante campos para tabela/carteirinha independente do shape exato
|
||||
return {
|
||||
id: p.id,
|
||||
nome: p.nome ?? p.nome_completo ?? '',
|
||||
nomeSocial: p.nome_social ?? p.nomeSocial ?? '',
|
||||
cpf: p.cpf ?? '',
|
||||
contato: {
|
||||
email: p.email ?? p.contato?.email ?? '',
|
||||
celular: p.telefone ?? p.contato?.celular ?? p.contato?.tel1 ?? p.contato?.tel2 ?? ''
|
||||
},
|
||||
endereco: {
|
||||
cidade: p.endereco?.cidade ?? p.cidade ?? '',
|
||||
uf: p.endereco?.estado ?? p.uf ?? p.estado ?? ''
|
||||
},
|
||||
dataNascimento: p.data_nascimento ?? p.nasc ?? p.dataNascimento ?? '',
|
||||
ultimaConsulta: p.ultima_consulta ?? p.ultimaConsulta ?? '',
|
||||
proximaConsulta: p.proxima_consulta ?? p.proximaConsulta ?? '',
|
||||
genero: p.genero ?? p.sexo ?? '',
|
||||
observacoes: p.observacoes ?? p.obs ?? '',
|
||||
status: p.status ?? ''
|
||||
};
|
||||
}
|
||||
|
||||
function blobPaciente(p){
|
||||
return normalize(`
|
||||
${p.nome||''} ${p.nomeSocial||''} ${p.cpf||''}
|
||||
${p.contato?.email||''} ${p.contato?.celular||''}
|
||||
${p.endereco?.cidade||''} ${p.endereco?.uf||''}
|
||||
`);
|
||||
}
|
||||
|
||||
/* ========================= Botão: Novo Paciente (cria na API) ========================= */
|
||||
function gerarNovoPaciente() {
|
||||
const hoje = new Date();
|
||||
const yyyy = hoje.getFullYear() - 30;
|
||||
const mm = String(hoje.getMonth() + 1).padStart(2, '0');
|
||||
const dd = String(hoje.getDate()).padStart(2, '0');
|
||||
|
||||
return {
|
||||
nome: 'Paciente Novo',
|
||||
nome_social: 'Novo',
|
||||
cpf: '111.222.333-44', // troque por CPF válido se sua API validar
|
||||
rg: '00.000.000-0',
|
||||
sexo: 'não informado',
|
||||
data_nascimento: `${yyyy}-${mm}-${dd}`,
|
||||
profissao: '—',
|
||||
estado_civil: 'solteiro(a)',
|
||||
contato: { email: 'novo@exemplo.com', celular: '+55 (00) 00000-0000' },
|
||||
endereco: {
|
||||
cep: '00000-000', logradouro: '—', numero: '—',
|
||||
bairro: '—', cidade: '—', estado: '—'
|
||||
},
|
||||
observacoes: 'Registro criado automaticamente pelo botão "Novo paciente".'
|
||||
};
|
||||
}
|
||||
|
||||
async function criarEIrParaCadastro() {
|
||||
try {
|
||||
btnNew?.setAttribute('aria-busy', 'true');
|
||||
btnNew?.classList.add('is-busy');
|
||||
btnNew && (btnNew.style.pointerEvents = 'none');
|
||||
|
||||
const novo = await createPaciente(gerarNovoPaciente());
|
||||
const newId = novo?.id;
|
||||
if (!newId) throw new Error('A API não retornou o ID do novo paciente.');
|
||||
location.href = `cadastro.html?id=${encodeURIComponent(newId)}`;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
alert(`Falha ao criar paciente: ${err.message}`);
|
||||
location.href = 'cadastro.html';
|
||||
} finally {
|
||||
btnNew?.removeAttribute('aria-busy');
|
||||
btnNew?.classList.remove('is-busy');
|
||||
if (btnNew) btnNew.style.pointerEvents = '';
|
||||
}
|
||||
}
|
||||
|
||||
btnNew?.addEventListener('click', (ev)=>{ ev.preventDefault(); criarEIrParaCadastro(); });
|
||||
|
||||
/* ========================= Render (lista/paginação/contador) ========================= */
|
||||
function render(){
|
||||
// filtro local (client-side). Se quiser, mude para query no servidor.
|
||||
const term = normalize(filtro);
|
||||
const list = term ? pacientes.filter(p => blobPaciente(p).includes(term)) : pacientes.slice();
|
||||
|
||||
const total = list.length;
|
||||
const pages = Math.max(1, Math.ceil(total / perPage));
|
||||
if (page > pages) page = pages;
|
||||
|
||||
const start = (page - 1) * perPage;
|
||||
const rows = list.slice(start, start + perPage);
|
||||
|
||||
// tabela
|
||||
if (tbody) {
|
||||
tbody.innerHTML = rows.length ? rows.map((p, i) => `
|
||||
<tr>
|
||||
<td>${fmtIndex(start + i + 1)}</td>
|
||||
<td>
|
||||
${p.nome || '—'}
|
||||
${p.nomeSocial ? `<div style="font-size:12px;color:#64748b">(${p.nomeSocial})</div>` : ''}
|
||||
</td>
|
||||
<td>${p.cpf || '—'}</td>
|
||||
<td>${p.contato?.email || '—'}</td>
|
||||
<td>${p.contato?.celular || '—'}</td>
|
||||
<td>${p.endereco?.cidade ? `${p.endereco.cidade}${p.endereco.uf ? '/' + p.endereco.uf : ''}` : '—'}</td>
|
||||
<td class="col-actions" style="text-align:right; white-space:nowrap;">
|
||||
<button class="page-btn btn-view" type="button" data-id="${p.id}" title="Ver carteirinha" aria-label="Ver carteirinha">👁️</button>
|
||||
<button class="page-btn btn-edit" type="button" data-id="${p.id}" title="Editar">✏️</button>
|
||||
<button class="page-btn btn-del" type="button" data-id="${p.id}" title="Excluir">🗑️</button>
|
||||
</td>
|
||||
</tr>
|
||||
`).join('') : `
|
||||
<tr><td colspan="7" style="padding:16px;color:#64748b">Sem pacientes cadastrados.</td></tr>
|
||||
`;
|
||||
}
|
||||
|
||||
// ações (delegadas depois do render)
|
||||
$$('[data-id].btn-edit').forEach(b => b.onclick = () => onEdit(b.dataset.id));
|
||||
$$('[data-id].btn-del').forEach(b => b.onclick = () => onDelete(b.dataset.id));
|
||||
$$('[data-id].btn-view').forEach(b => b.onclick = () => onView(b.dataset.id));
|
||||
|
||||
// paginação
|
||||
if (pager) {
|
||||
pager.innerHTML = `
|
||||
<button class="page-btn" ${page<=1?'disabled':''} id="pgPrev">«</button>
|
||||
${Array.from({length: pages}, (_, i) =>
|
||||
`<button class="page-btn ${i+1===page?'active':''}" data-page="${i+1}">${i+1}</button>`
|
||||
).join('')}
|
||||
<button class="page-btn" ${page>=pages?'disabled':''} id="pgNext">»</button>
|
||||
`;
|
||||
$('#pgPrev')?.addEventListener('click', ()=>{ if(page>1){ page--; render(); } });
|
||||
$('#pgNext')?.addEventListener('click', ()=>{ if(page<pages){ page++; render(); } });
|
||||
$$('[data-page]').forEach(btn => btn.addEventListener('click', ()=>{ page = +btn.dataset.page; render(); }));
|
||||
}
|
||||
|
||||
// contador
|
||||
if (countLabel) {
|
||||
const showing = rows.length;
|
||||
countLabel.textContent = `Mostrando ${showing} de ${total} paciente(s)`;
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================= Carregar dados da API ========================= */
|
||||
async function fetchAndRender(initialQuery=''){
|
||||
try {
|
||||
// busca no servidor (seu service já desempacota { rows })
|
||||
const { rows } = await listPacientes({ q: initialQuery });
|
||||
// normaliza para o shape usado pela UI
|
||||
pacientes = rows.map(fromApi);
|
||||
|
||||
// ordena por próxima consulta (opcional)
|
||||
pacientes.sort((a,b) => new Date(a.proximaConsulta||'9999-12-31') - new Date(b.proximaConsulta||'9999-12-31'));
|
||||
|
||||
render();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
if (tbody) tbody.innerHTML = `<tr><td colspan="7" style="padding:16px;color:#ef4444">Erro ao carregar: ${err.message}</td></tr>`;
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================= Ações ========================= */
|
||||
function onEdit(id){ window.location.href = `cadastro.html?id=${encodeURIComponent(id)}`; }
|
||||
|
||||
async function onDelete(id){
|
||||
if(!confirm('Deseja excluir este paciente?')) return;
|
||||
try {
|
||||
await deletePaciente(id);
|
||||
// remove do cache local e re-renderiza
|
||||
pacientes = pacientes.filter(p => String(p.id) !== String(id));
|
||||
render();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
alert('Falha ao excluir paciente.');
|
||||
}
|
||||
}
|
||||
|
||||
async function onView(id){
|
||||
try{
|
||||
// tenta no cache (lista) primeiro
|
||||
let p = pacientes.find(x => String(x.id) === String(id));
|
||||
if (!p) {
|
||||
const apiItem = await getPaciente(id);
|
||||
p = fromApi(apiItem || {});
|
||||
}
|
||||
abrirCarteirinha(p);
|
||||
}catch(e){
|
||||
console.error(e);
|
||||
alert('Não foi possível carregar os dados deste paciente.');
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================= Eventos UI ========================= */
|
||||
q?.addEventListener('input', () => { filtro = q.value || ''; page = 1; render(); });
|
||||
|
||||
/* ========================= Inicializa (carrega da API) ========================= */
|
||||
fetchAndRender();
|
||||
|
||||
/* ========================= MODAL Carteirinha ========================= */
|
||||
const overlay = document.getElementById('carteirinha-overlay');
|
||||
const closeBtn = document.querySelector('.close-btn');
|
||||
|
||||
function cId(id){ return document.getElementById(id); }
|
||||
|
||||
function preencherCarteirinha(p){
|
||||
if(!p){
|
||||
alert('Não foi possível encontrar este paciente.');
|
||||
return;
|
||||
}
|
||||
const nascimento =
|
||||
p.dataNascimento ?? p.nascimento ?? p.dataNasc ?? p.dtNascimento ??
|
||||
p.data_nascimento ?? p.dataDeNascimento ?? p.dt_nasc ?? p.nasc;
|
||||
|
||||
const genero =
|
||||
p.genero ?? p.sexo ?? p.generoBiologico ?? p.genero_identidade ?? p['gênero'];
|
||||
|
||||
const obs =
|
||||
p.observacoes ?? p.obs ?? p.anotacoes ?? p.observacao ?? p.notas;
|
||||
|
||||
const idadeCalc = nascimento ? calcIdade(nascimento) : null;
|
||||
const idadeTxt = (idadeCalc != null) ? `${idadeCalc} anos` : '—';
|
||||
|
||||
cId('c-nome') && (cId('c-nome').textContent = p.nome || '—');
|
||||
cId('c-idade') && (cId('c-idade').textContent = idadeTxt);
|
||||
cId('c-genero') && (cId('c-genero').textContent = normalizaGenero(genero) || '—');
|
||||
cId('c-cpf') && (cId('c-cpf').textContent = formatCPF(p.cpf));
|
||||
cId('c-ultima') && (cId('c-ultima').textContent = formatData(p.ultimaConsulta ?? p.ultima_consulta ?? p.ultConsulta));
|
||||
cId('c-proxima') && (cId('c-proxima').textContent = formatData(p.proximaConsulta ?? p.proxima_consulta ?? p.proxConsulta));
|
||||
cId('c-observacoes')&& (cId('c-observacoes').textContent = obs || '—');
|
||||
cId('c-iniciais') && (cId('c-iniciais').textContent = iniciais(p.nome));
|
||||
|
||||
const chipStatus = document.getElementById('chip-status');
|
||||
if (chipStatus) chipStatus.textContent = p.status ? `Paciente ${String(p.status).toLowerCase()}` : 'Paciente ativo';
|
||||
|
||||
const chipProx = document.getElementById('chip-prox');
|
||||
const dProx = p.proximaConsulta ?? p.proxima_consulta ?? p.proxConsulta;
|
||||
if (chipProx) chipProx.textContent = dProx ? `Próx.: ${formatData(dProx)}` : '—';
|
||||
}
|
||||
|
||||
function abrirCarteirinha(paciente){
|
||||
if (!overlay) {
|
||||
alert('Estrutura da carteirinha não está no HTML desta página.');
|
||||
console.warn('⚠️ Elemento #carteirinha-overlay não encontrado no DOM.');
|
||||
return;
|
||||
}
|
||||
preencherCarteirinha(paciente);
|
||||
overlay.setAttribute('aria-hidden','false');
|
||||
|
||||
const card = document.getElementById('carteirinha');
|
||||
if (card) {
|
||||
card.style.animation = 'none';
|
||||
void card.offsetWidth;
|
||||
card.style.animation = 'cardEnter .35s cubic-bezier(.22,.9,.27,1.05) forwards';
|
||||
}
|
||||
}
|
||||
function fecharCarteirinha(){ overlay?.setAttribute('aria-hidden','true'); }
|
||||
|
||||
closeBtn?.addEventListener('click', fecharCarteirinha);
|
||||
overlay?.addEventListener('click', (e)=>{ if(e.target === overlay) fecharCarteirinha(); });
|
||||
document.addEventListener('keydown', (e)=>{ if(e.key === 'Escape') fecharCarteirinha(); });
|
||||
|
||||
document.getElementById('btn-copiar')?.addEventListener('click', async ()=>{
|
||||
const texto =
|
||||
`Nome: ${byId('c-nome')?.textContent||''}
|
||||
Idade: ${byId('c-idade')?.textContent||''}
|
||||
Gênero: ${byId('c-genero')?.textContent||''}
|
||||
CPF: ${byId('c-cpf')?.textContent||''}
|
||||
Última consulta: ${byId('c-ultima')?.textContent||''}
|
||||
Próxima consulta: ${byId('c-proxima')?.textContent||''}
|
||||
Observações: ${byId('c-observacoes')?.textContent||''}`;
|
||||
try{
|
||||
await navigator.clipboard.writeText(texto);
|
||||
alert('Dados copiados! ✅');
|
||||
}catch{
|
||||
alert('Não foi possível copiar.');
|
||||
}
|
||||
});
|
||||
document.getElementById('btn-imprimir')?.addEventListener('click', ()=>{ window.print(); });
|
||||
195
HealthOneProject/assets/js/main.js
Normal file
@ -0,0 +1,195 @@
|
||||
/**
|
||||
* Template Name: Medicio
|
||||
* Template URL: https://bootstrapmade.com/medicio-free-bootstrap-theme/
|
||||
* Updated: Aug 07 2024 with Bootstrap v5.3.3
|
||||
* Author: BootstrapMade.com
|
||||
* License: https://bootstrapmade.com/license/
|
||||
*/
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Apply .scrolled class to the body as the page is scrolled down
|
||||
*/
|
||||
function toggleScrolled() {
|
||||
const selectBody = document.querySelector('body');
|
||||
const selectHeader = document.querySelector('#header');
|
||||
if (!selectHeader.classList.contains('scroll-up-sticky') && !selectHeader.classList.contains('sticky-top') && !selectHeader.classList.contains('fixed-top')) return;
|
||||
window.scrollY > 100 ? selectBody.classList.add('scrolled') : selectBody.classList.remove('scrolled');
|
||||
}
|
||||
|
||||
document.addEventListener('scroll', toggleScrolled);
|
||||
window.addEventListener('load', toggleScrolled);
|
||||
|
||||
/**
|
||||
* Mobile nav toggle
|
||||
*/
|
||||
const mobileNavToggleBtn = document.querySelector('.mobile-nav-toggle');
|
||||
|
||||
function mobileNavToogle() {
|
||||
document.querySelector('body').classList.toggle('mobile-nav-active');
|
||||
mobileNavToggleBtn.classList.toggle('bi-list');
|
||||
mobileNavToggleBtn.classList.toggle('bi-x');
|
||||
}
|
||||
mobileNavToggleBtn.addEventListener('click', mobileNavToogle);
|
||||
|
||||
/**
|
||||
* Hide mobile nav on same-page/hash links
|
||||
*/
|
||||
document.querySelectorAll('#navmenu a').forEach(navmenu => {
|
||||
navmenu.addEventListener('click', () => {
|
||||
if (document.querySelector('.mobile-nav-active')) {
|
||||
mobileNavToogle();
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Toggle mobile nav dropdowns
|
||||
*/
|
||||
document.querySelectorAll('.navmenu .toggle-dropdown').forEach(navmenu => {
|
||||
navmenu.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
this.parentNode.classList.toggle('active');
|
||||
this.parentNode.nextElementSibling.classList.toggle('dropdown-active');
|
||||
e.stopImmediatePropagation();
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Preloader
|
||||
*/
|
||||
const preloader = document.querySelector('#preloader');
|
||||
if (preloader) {
|
||||
window.addEventListener('load', () => {
|
||||
preloader.remove();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Scroll top button
|
||||
*/
|
||||
let scrollTop = document.querySelector('.scroll-top');
|
||||
|
||||
function toggleScrollTop() {
|
||||
if (scrollTop) {
|
||||
window.scrollY > 100 ? scrollTop.classList.add('active') : scrollTop.classList.remove('active');
|
||||
}
|
||||
}
|
||||
scrollTop.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
});
|
||||
|
||||
window.addEventListener('load', toggleScrollTop);
|
||||
document.addEventListener('scroll', toggleScrollTop);
|
||||
|
||||
/**
|
||||
* Animation on scroll function and init
|
||||
*/
|
||||
function aosInit() {
|
||||
AOS.init({
|
||||
duration: 600,
|
||||
easing: 'ease-in-out',
|
||||
once: true,
|
||||
mirror: false
|
||||
});
|
||||
}
|
||||
window.addEventListener('load', aosInit);
|
||||
|
||||
/**
|
||||
* Auto generate the carousel indicators
|
||||
*/
|
||||
document.querySelectorAll('.carousel-indicators').forEach((carouselIndicator) => {
|
||||
carouselIndicator.closest('.carousel').querySelectorAll('.carousel-item').forEach((carouselItem, index) => {
|
||||
if (index === 0) {
|
||||
carouselIndicator.innerHTML += `<li data-bs-target="#${carouselIndicator.closest('.carousel').id}" data-bs-slide-to="${index}" class="active"></li>`;
|
||||
} else {
|
||||
carouselIndicator.innerHTML += `<li data-bs-target="#${carouselIndicator.closest('.carousel').id}" data-bs-slide-to="${index}"></li>`;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Initiate glightbox
|
||||
*/
|
||||
const glightbox = GLightbox({
|
||||
selector: '.glightbox'
|
||||
});
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Init swiper sliders
|
||||
*/
|
||||
function initSwiper() {
|
||||
document.querySelectorAll(".init-swiper").forEach(function(swiperElement) {
|
||||
let config = JSON.parse(
|
||||
swiperElement.querySelector(".swiper-config").innerHTML.trim()
|
||||
);
|
||||
|
||||
if (swiperElement.classList.contains("swiper-tab")) {
|
||||
initSwiperWithCustomPagination(swiperElement, config);
|
||||
} else {
|
||||
new Swiper(swiperElement, config);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener("load", initSwiper);
|
||||
|
||||
/**
|
||||
* Frequently Asked Questions Toggle
|
||||
*/
|
||||
document.querySelectorAll('.faq-item h3, .faq-item .faq-toggle').forEach((faqItem) => {
|
||||
faqItem.addEventListener('click', () => {
|
||||
faqItem.parentNode.classList.toggle('faq-active');
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Correct scrolling position upon page load for URLs containing hash links.
|
||||
*/
|
||||
window.addEventListener('load', function(e) {
|
||||
if (window.location.hash) {
|
||||
if (document.querySelector(window.location.hash)) {
|
||||
setTimeout(() => {
|
||||
let section = document.querySelector(window.location.hash);
|
||||
let scrollMarginTop = getComputedStyle(section).scrollMarginTop;
|
||||
window.scrollTo({
|
||||
top: section.offsetTop - parseInt(scrollMarginTop),
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Navmenu Scrollspy
|
||||
*/
|
||||
let navmenulinks = document.querySelectorAll('.navmenu a');
|
||||
|
||||
function navmenuScrollspy() {
|
||||
navmenulinks.forEach(navmenulink => {
|
||||
if (!navmenulink.hash) return;
|
||||
let section = document.querySelector(navmenulink.hash);
|
||||
if (!section) return;
|
||||
let position = window.scrollY + 200;
|
||||
if (position >= section.offsetTop && position <= (section.offsetTop + section.offsetHeight)) {
|
||||
document.querySelectorAll('.navmenu a.active').forEach(link => link.classList.remove('active'));
|
||||
navmenulink.classList.add('active');
|
||||
} else {
|
||||
navmenulink.classList.remove('active');
|
||||
}
|
||||
})
|
||||
}
|
||||
window.addEventListener('load', navmenuScrollspy);
|
||||
document.addEventListener('scroll', navmenuScrollspy);
|
||||
|
||||
})();
|
||||
53
HealthOneProject/assets/js/pacientesService.js
Normal file
@ -0,0 +1,53 @@
|
||||
// /js/pacientesService.js
|
||||
import { api } from './apiClient.js';
|
||||
|
||||
// se você tiver token, carregue aqui: const token = localStorage.getItem('token');
|
||||
|
||||
export async function listPacientes({ q, page=1, per_page=20 } = {}) {
|
||||
const params = new URLSearchParams();
|
||||
if (q) params.set('q', q);
|
||||
params.set('page', page);
|
||||
params.set('per_page', per_page);
|
||||
|
||||
const payload = await api(`/pacientes${params.toString() ? `?${params}` : ''}`, {
|
||||
method: 'GET',
|
||||
// token
|
||||
});
|
||||
// payload: { success, data: [...], pagination: {...} }
|
||||
return { rows: payload?.data || [], pagination: payload?.pagination || null };
|
||||
}
|
||||
|
||||
export async function getPaciente(id) {
|
||||
const payload = await api(`/pacientes/${encodeURIComponent(id)}`, {
|
||||
method: 'GET',
|
||||
// token
|
||||
});
|
||||
return payload?.data || null;
|
||||
}
|
||||
|
||||
export async function createPaciente(data) {
|
||||
const payload = await api(`/pacientes`, {
|
||||
method: 'POST',
|
||||
data,
|
||||
// token
|
||||
});
|
||||
// retorna { success, message, data: { id, ... } }
|
||||
return payload?.data || null;
|
||||
}
|
||||
|
||||
export async function updatePaciente(id, data) {
|
||||
const payload = await api(`/pacientes/${encodeURIComponent(id)}`, {
|
||||
method: 'PUT',
|
||||
data,
|
||||
// token
|
||||
});
|
||||
return payload?.data || null;
|
||||
}
|
||||
|
||||
export async function deletePaciente(id) {
|
||||
await api(`/pacientes/${encodeURIComponent(id)}`, {
|
||||
method: 'DELETE',
|
||||
// token
|
||||
});
|
||||
return true;
|
||||
}
|
||||
2
HealthOneProject/assets/scss/Readme.txt
Normal file
@ -0,0 +1,2 @@
|
||||
The .scss (Sass) files are only available in the pro version.
|
||||
You can buy it from: https://bootstrapmade.com/medicio-free-bootstrap-theme/
|
||||
614
HealthOneProject/assets/vendor/aos/aos.cjs.js
vendored
Normal file
@ -0,0 +1,614 @@
|
||||
'use strict';
|
||||
|
||||
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
||||
|
||||
var throttle = _interopDefault(require('lodash.throttle'));
|
||||
var debounce = _interopDefault(require('lodash.debounce'));
|
||||
|
||||
var callback = function callback() {};
|
||||
|
||||
function containsAOSNode(nodes) {
|
||||
var i = void 0,
|
||||
currentNode = void 0,
|
||||
result = void 0;
|
||||
|
||||
for (i = 0; i < nodes.length; i += 1) {
|
||||
currentNode = nodes[i];
|
||||
|
||||
if (currentNode.dataset && currentNode.dataset.aos) {
|
||||
return true;
|
||||
}
|
||||
|
||||
result = currentNode.children && containsAOSNode(currentNode.children);
|
||||
|
||||
if (result) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function check(mutations) {
|
||||
if (!mutations) return;
|
||||
|
||||
mutations.forEach(function (mutation) {
|
||||
var addedNodes = Array.prototype.slice.call(mutation.addedNodes);
|
||||
var removedNodes = Array.prototype.slice.call(mutation.removedNodes);
|
||||
var allNodes = addedNodes.concat(removedNodes);
|
||||
|
||||
if (containsAOSNode(allNodes)) {
|
||||
return callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getMutationObserver() {
|
||||
return window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
|
||||
}
|
||||
|
||||
function isSupported() {
|
||||
return !!getMutationObserver();
|
||||
}
|
||||
|
||||
function ready(selector, fn) {
|
||||
var doc = window.document;
|
||||
var MutationObserver = getMutationObserver();
|
||||
|
||||
var observer = new MutationObserver(check);
|
||||
callback = fn;
|
||||
|
||||
observer.observe(doc.documentElement, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
removedNodes: true
|
||||
});
|
||||
}
|
||||
|
||||
var observer = { isSupported: isSupported, ready: ready };
|
||||
|
||||
var classCallCheck = function (instance, Constructor) {
|
||||
if (!(instance instanceof Constructor)) {
|
||||
throw new TypeError("Cannot call a class as a function");
|
||||
}
|
||||
};
|
||||
|
||||
var createClass = function () {
|
||||
function defineProperties(target, props) {
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
var descriptor = props[i];
|
||||
descriptor.enumerable = descriptor.enumerable || false;
|
||||
descriptor.configurable = true;
|
||||
if ("value" in descriptor) descriptor.writable = true;
|
||||
Object.defineProperty(target, descriptor.key, descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
return function (Constructor, protoProps, staticProps) {
|
||||
if (protoProps) defineProperties(Constructor.prototype, protoProps);
|
||||
if (staticProps) defineProperties(Constructor, staticProps);
|
||||
return Constructor;
|
||||
};
|
||||
}();
|
||||
|
||||
var _extends = Object.assign || function (target) {
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
var source = arguments[i];
|
||||
|
||||
for (var key in source) {
|
||||
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
};
|
||||
|
||||
/**
|
||||
* Device detector
|
||||
*/
|
||||
|
||||
var fullNameRe = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i;
|
||||
var prefixRe = /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i;
|
||||
var fullNameMobileRe = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i;
|
||||
var prefixMobileRe = /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i;
|
||||
|
||||
function ua() {
|
||||
return navigator.userAgent || navigator.vendor || window.opera || '';
|
||||
}
|
||||
|
||||
var Detector = function () {
|
||||
function Detector() {
|
||||
classCallCheck(this, Detector);
|
||||
}
|
||||
|
||||
createClass(Detector, [{
|
||||
key: 'phone',
|
||||
value: function phone() {
|
||||
var a = ua();
|
||||
return !!(fullNameRe.test(a) || prefixRe.test(a.substr(0, 4)));
|
||||
}
|
||||
}, {
|
||||
key: 'mobile',
|
||||
value: function mobile() {
|
||||
var a = ua();
|
||||
return !!(fullNameMobileRe.test(a) || prefixMobileRe.test(a.substr(0, 4)));
|
||||
}
|
||||
}, {
|
||||
key: 'tablet',
|
||||
value: function tablet() {
|
||||
return this.mobile() && !this.phone();
|
||||
}
|
||||
|
||||
// http://browserhacks.com/#hack-acea075d0ac6954f275a70023906050c
|
||||
|
||||
}, {
|
||||
key: 'ie11',
|
||||
value: function ie11() {
|
||||
return '-ms-scroll-limit' in document.documentElement.style && '-ms-ime-align' in document.documentElement.style;
|
||||
}
|
||||
}]);
|
||||
return Detector;
|
||||
}();
|
||||
|
||||
var detect = new Detector();
|
||||
|
||||
/**
|
||||
* Adds multiple classes on node
|
||||
* @param {DOMNode} node
|
||||
* @param {array} classes
|
||||
*/
|
||||
var addClasses = function addClasses(node, classes) {
|
||||
return classes && classes.forEach(function (className) {
|
||||
return node.classList.add(className);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes multiple classes from node
|
||||
* @param {DOMNode} node
|
||||
* @param {array} classes
|
||||
*/
|
||||
var removeClasses = function removeClasses(node, classes) {
|
||||
return classes && classes.forEach(function (className) {
|
||||
return node.classList.remove(className);
|
||||
});
|
||||
};
|
||||
|
||||
var fireEvent = function fireEvent(eventName, data) {
|
||||
var customEvent = void 0;
|
||||
|
||||
if (detect.ie11()) {
|
||||
customEvent = document.createEvent('CustomEvent');
|
||||
customEvent.initCustomEvent(eventName, true, true, { detail: data });
|
||||
} else {
|
||||
customEvent = new CustomEvent(eventName, {
|
||||
detail: data
|
||||
});
|
||||
}
|
||||
|
||||
return document.dispatchEvent(customEvent);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set or remove aos-animate class
|
||||
* @param {node} el element
|
||||
* @param {int} top scrolled distance
|
||||
*/
|
||||
var applyClasses = function applyClasses(el, top) {
|
||||
var options = el.options,
|
||||
position = el.position,
|
||||
node = el.node,
|
||||
data = el.data;
|
||||
|
||||
|
||||
var hide = function hide() {
|
||||
if (!el.animated) return;
|
||||
|
||||
removeClasses(node, options.animatedClassNames);
|
||||
fireEvent('aos:out', node);
|
||||
|
||||
if (el.options.id) {
|
||||
fireEvent('aos:in:' + el.options.id, node);
|
||||
}
|
||||
|
||||
el.animated = false;
|
||||
};
|
||||
|
||||
var show = function show() {
|
||||
if (el.animated) return;
|
||||
|
||||
addClasses(node, options.animatedClassNames);
|
||||
|
||||
fireEvent('aos:in', node);
|
||||
if (el.options.id) {
|
||||
fireEvent('aos:in:' + el.options.id, node);
|
||||
}
|
||||
|
||||
el.animated = true;
|
||||
};
|
||||
|
||||
if (options.mirror && top >= position.out && !options.once) {
|
||||
hide();
|
||||
} else if (top >= position.in) {
|
||||
show();
|
||||
} else if (el.animated && !options.once) {
|
||||
hide();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Scroll logic - add or remove 'aos-animate' class on scroll
|
||||
*
|
||||
* @param {array} $elements array of elements nodes
|
||||
* @return {void}
|
||||
*/
|
||||
var handleScroll = function handleScroll($elements) {
|
||||
return $elements.forEach(function (el, i) {
|
||||
return applyClasses(el, window.pageYOffset);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get offset of DOM element
|
||||
* like there were no transforms applied on it
|
||||
*
|
||||
* @param {Node} el [DOM element]
|
||||
* @return {Object} [top and left offset]
|
||||
*/
|
||||
var offset = function offset(el) {
|
||||
var _x = 0;
|
||||
var _y = 0;
|
||||
|
||||
while (el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) {
|
||||
_x += el.offsetLeft - (el.tagName != 'BODY' ? el.scrollLeft : 0);
|
||||
_y += el.offsetTop - (el.tagName != 'BODY' ? el.scrollTop : 0);
|
||||
el = el.offsetParent;
|
||||
}
|
||||
|
||||
return {
|
||||
top: _y,
|
||||
left: _x
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Get inline option with a fallback.
|
||||
*
|
||||
* @param {Node} el [Dom element]
|
||||
* @param {String} key [Option key]
|
||||
* @param {String} fallback [Default (fallback) value]
|
||||
* @return {Mixed} [Option set with inline attributes or fallback value if not set]
|
||||
*/
|
||||
|
||||
var getInlineOption = (function (el, key, fallback) {
|
||||
var attr = el.getAttribute('data-aos-' + key);
|
||||
|
||||
if (typeof attr !== 'undefined') {
|
||||
if (attr === 'true') {
|
||||
return true;
|
||||
} else if (attr === 'false') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return attr || fallback;
|
||||
});
|
||||
|
||||
/**
|
||||
* Calculate offset
|
||||
* basing on element's settings like:
|
||||
* - anchor
|
||||
* - offset
|
||||
*
|
||||
* @param {Node} el [Dom element]
|
||||
* @return {Integer} [Final offset that will be used to trigger animation in good position]
|
||||
*/
|
||||
|
||||
var getPositionIn = function getPositionIn(el, defaultOffset, defaultAnchorPlacement) {
|
||||
var windowHeight = window.innerHeight;
|
||||
var anchor = getInlineOption(el, 'anchor');
|
||||
var inlineAnchorPlacement = getInlineOption(el, 'anchor-placement');
|
||||
var additionalOffset = Number(getInlineOption(el, 'offset', inlineAnchorPlacement ? 0 : defaultOffset));
|
||||
var anchorPlacement = inlineAnchorPlacement || defaultAnchorPlacement;
|
||||
var finalEl = el;
|
||||
|
||||
if (anchor && document.querySelectorAll(anchor)) {
|
||||
finalEl = document.querySelectorAll(anchor)[0];
|
||||
}
|
||||
|
||||
var triggerPoint = offset(finalEl).top - windowHeight;
|
||||
|
||||
switch (anchorPlacement) {
|
||||
case 'top-bottom':
|
||||
// Default offset
|
||||
break;
|
||||
case 'center-bottom':
|
||||
triggerPoint += finalEl.offsetHeight / 2;
|
||||
break;
|
||||
case 'bottom-bottom':
|
||||
triggerPoint += finalEl.offsetHeight;
|
||||
break;
|
||||
case 'top-center':
|
||||
triggerPoint += windowHeight / 2;
|
||||
break;
|
||||
case 'center-center':
|
||||
triggerPoint += windowHeight / 2 + finalEl.offsetHeight / 2;
|
||||
break;
|
||||
case 'bottom-center':
|
||||
triggerPoint += windowHeight / 2 + finalEl.offsetHeight;
|
||||
break;
|
||||
case 'top-top':
|
||||
triggerPoint += windowHeight;
|
||||
break;
|
||||
case 'bottom-top':
|
||||
triggerPoint += windowHeight + finalEl.offsetHeight;
|
||||
break;
|
||||
case 'center-top':
|
||||
triggerPoint += windowHeight + finalEl.offsetHeight / 2;
|
||||
break;
|
||||
}
|
||||
|
||||
return triggerPoint + additionalOffset;
|
||||
};
|
||||
|
||||
var getPositionOut = function getPositionOut(el, defaultOffset) {
|
||||
var windowHeight = window.innerHeight;
|
||||
var anchor = getInlineOption(el, 'anchor');
|
||||
var additionalOffset = getInlineOption(el, 'offset', defaultOffset);
|
||||
var finalEl = el;
|
||||
|
||||
if (anchor && document.querySelectorAll(anchor)) {
|
||||
finalEl = document.querySelectorAll(anchor)[0];
|
||||
}
|
||||
|
||||
var elementOffsetTop = offset(finalEl).top;
|
||||
|
||||
return elementOffsetTop + finalEl.offsetHeight - additionalOffset;
|
||||
};
|
||||
|
||||
/* Clearing variables */
|
||||
|
||||
var prepare = function prepare($elements, options) {
|
||||
$elements.forEach(function (el, i) {
|
||||
var mirror = getInlineOption(el.node, 'mirror', options.mirror);
|
||||
var once = getInlineOption(el.node, 'once', options.once);
|
||||
var id = getInlineOption(el.node, 'id');
|
||||
var customClassNames = options.useClassNames && el.node.getAttribute('data-aos');
|
||||
|
||||
var animatedClassNames = [options.animatedClassName].concat(customClassNames ? customClassNames.split(' ') : []).filter(function (className) {
|
||||
return typeof className === 'string';
|
||||
});
|
||||
|
||||
if (options.initClassName) {
|
||||
el.node.classList.add(options.initClassName);
|
||||
}
|
||||
|
||||
el.position = {
|
||||
in: getPositionIn(el.node, options.offset, options.anchorPlacement),
|
||||
out: mirror && getPositionOut(el.node, options.offset)
|
||||
};
|
||||
|
||||
el.options = {
|
||||
once: once,
|
||||
mirror: mirror,
|
||||
animatedClassNames: animatedClassNames,
|
||||
id: id
|
||||
};
|
||||
});
|
||||
|
||||
return $elements;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate initial array with elements as objects
|
||||
* This array will be extended later with elements attributes values
|
||||
* like 'position'
|
||||
*/
|
||||
var elements = (function () {
|
||||
var elements = document.querySelectorAll('[data-aos]');
|
||||
return Array.prototype.map.call(elements, function (node) {
|
||||
return { node: node };
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* *******************************************************
|
||||
* AOS (Animate on scroll) - wowjs alternative
|
||||
* made to animate elements on scroll in both directions
|
||||
* *******************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
* Private variables
|
||||
*/
|
||||
var $aosElements = [];
|
||||
var initialized = false;
|
||||
|
||||
/**
|
||||
* Default options
|
||||
*/
|
||||
var options = {
|
||||
offset: 120,
|
||||
delay: 0,
|
||||
easing: 'ease',
|
||||
duration: 400,
|
||||
disable: false,
|
||||
once: false,
|
||||
mirror: false,
|
||||
anchorPlacement: 'top-bottom',
|
||||
startEvent: 'DOMContentLoaded',
|
||||
animatedClassName: 'aos-animate',
|
||||
initClassName: 'aos-init',
|
||||
useClassNames: false,
|
||||
disableMutationObserver: false,
|
||||
throttleDelay: 99,
|
||||
debounceDelay: 50
|
||||
};
|
||||
|
||||
// Detect not supported browsers (<=IE9)
|
||||
// http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805
|
||||
var isBrowserNotSupported = function isBrowserNotSupported() {
|
||||
return document.all && !window.atob;
|
||||
};
|
||||
|
||||
var initializeScroll = function initializeScroll() {
|
||||
// Extend elements objects in $aosElements with their positions
|
||||
$aosElements = prepare($aosElements, options);
|
||||
// Perform scroll event, to refresh view and show/hide elements
|
||||
handleScroll($aosElements);
|
||||
|
||||
/**
|
||||
* Handle scroll event to animate elements on scroll
|
||||
*/
|
||||
window.addEventListener('scroll', throttle(function () {
|
||||
handleScroll($aosElements, options.once);
|
||||
}, options.throttleDelay));
|
||||
|
||||
return $aosElements;
|
||||
};
|
||||
|
||||
/**
|
||||
* Refresh AOS
|
||||
*/
|
||||
var refresh = function refresh() {
|
||||
var initialize = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
||||
|
||||
// Allow refresh only when it was first initialized on startEvent
|
||||
if (initialize) initialized = true;
|
||||
if (initialized) initializeScroll();
|
||||
};
|
||||
|
||||
/**
|
||||
* Hard refresh
|
||||
* create array with new elements and trigger refresh
|
||||
*/
|
||||
var refreshHard = function refreshHard() {
|
||||
$aosElements = elements();
|
||||
|
||||
if (isDisabled(options.disable) || isBrowserNotSupported()) {
|
||||
return disable();
|
||||
}
|
||||
|
||||
refresh();
|
||||
};
|
||||
|
||||
/**
|
||||
* Disable AOS
|
||||
* Remove all attributes to reset applied styles
|
||||
*/
|
||||
var disable = function disable() {
|
||||
$aosElements.forEach(function (el, i) {
|
||||
el.node.removeAttribute('data-aos');
|
||||
el.node.removeAttribute('data-aos-easing');
|
||||
el.node.removeAttribute('data-aos-duration');
|
||||
el.node.removeAttribute('data-aos-delay');
|
||||
|
||||
if (options.initClassName) {
|
||||
el.node.classList.remove(options.initClassName);
|
||||
}
|
||||
|
||||
if (options.animatedClassName) {
|
||||
el.node.classList.remove(options.animatedClassName);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if AOS should be disabled based on provided setting
|
||||
*/
|
||||
var isDisabled = function isDisabled(optionDisable) {
|
||||
return optionDisable === true || optionDisable === 'mobile' && detect.mobile() || optionDisable === 'phone' && detect.phone() || optionDisable === 'tablet' && detect.tablet() || typeof optionDisable === 'function' && optionDisable() === true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializing AOS
|
||||
* - Create options merging defaults with user defined options
|
||||
* - Set attributes on <body> as global setting - css relies on it
|
||||
* - Attach preparing elements to options.startEvent,
|
||||
* window resize and orientation change
|
||||
* - Attach function that handle scroll and everything connected to it
|
||||
* to window scroll event and fire once document is ready to set initial state
|
||||
*/
|
||||
var init = function init(settings) {
|
||||
options = _extends(options, settings);
|
||||
|
||||
// Create initial array with elements -> to be fullfilled later with prepare()
|
||||
$aosElements = elements();
|
||||
|
||||
/**
|
||||
* Disable mutation observing if not supported
|
||||
*/
|
||||
if (!options.disableMutationObserver && !observer.isSupported()) {
|
||||
console.info('\n aos: MutationObserver is not supported on this browser,\n code mutations observing has been disabled.\n You may have to call "refreshHard()" by yourself.\n ');
|
||||
options.disableMutationObserver = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Observe [aos] elements
|
||||
* If something is loaded by AJAX
|
||||
* it'll refresh plugin automatically
|
||||
*/
|
||||
if (!options.disableMutationObserver) {
|
||||
observer.ready('[data-aos]', refreshHard);
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't init plugin if option `disable` is set
|
||||
* or when browser is not supported
|
||||
*/
|
||||
if (isDisabled(options.disable) || isBrowserNotSupported()) {
|
||||
return disable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set global settings on body, based on options
|
||||
* so CSS can use it
|
||||
*/
|
||||
document.querySelector('body').setAttribute('data-aos-easing', options.easing);
|
||||
|
||||
document.querySelector('body').setAttribute('data-aos-duration', options.duration);
|
||||
|
||||
document.querySelector('body').setAttribute('data-aos-delay', options.delay);
|
||||
|
||||
/**
|
||||
* Handle initializing
|
||||
*/
|
||||
if (['DOMContentLoaded', 'load'].indexOf(options.startEvent) === -1) {
|
||||
// Listen to options.startEvent and initialize AOS
|
||||
document.addEventListener(options.startEvent, function () {
|
||||
refresh(true);
|
||||
});
|
||||
} else {
|
||||
window.addEventListener('load', function () {
|
||||
refresh(true);
|
||||
});
|
||||
}
|
||||
|
||||
if (options.startEvent === 'DOMContentLoaded' && ['complete', 'interactive'].indexOf(document.readyState) > -1) {
|
||||
// Initialize AOS if default startEvent was already fired
|
||||
refresh(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh plugin on window resize or orientation change
|
||||
*/
|
||||
window.addEventListener('resize', debounce(refresh, options.debounceDelay, true));
|
||||
|
||||
window.addEventListener('orientationchange', debounce(refresh, options.debounceDelay, true));
|
||||
|
||||
return $aosElements;
|
||||
};
|
||||
|
||||
/**
|
||||
* Export Public API
|
||||
*/
|
||||
|
||||
var aos = {
|
||||
init: init,
|
||||
refresh: refresh,
|
||||
refreshHard: refreshHard
|
||||
};
|
||||
|
||||
module.exports = aos;
|
||||
1
HealthOneProject/assets/vendor/aos/aos.css
vendored
Normal file
610
HealthOneProject/assets/vendor/aos/aos.esm.js
vendored
Normal file
@ -0,0 +1,610 @@
|
||||
import throttle from 'lodash.throttle';
|
||||
import debounce from 'lodash.debounce';
|
||||
|
||||
var callback = function callback() {};
|
||||
|
||||
function containsAOSNode(nodes) {
|
||||
var i = void 0,
|
||||
currentNode = void 0,
|
||||
result = void 0;
|
||||
|
||||
for (i = 0; i < nodes.length; i += 1) {
|
||||
currentNode = nodes[i];
|
||||
|
||||
if (currentNode.dataset && currentNode.dataset.aos) {
|
||||
return true;
|
||||
}
|
||||
|
||||
result = currentNode.children && containsAOSNode(currentNode.children);
|
||||
|
||||
if (result) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function check(mutations) {
|
||||
if (!mutations) return;
|
||||
|
||||
mutations.forEach(function (mutation) {
|
||||
var addedNodes = Array.prototype.slice.call(mutation.addedNodes);
|
||||
var removedNodes = Array.prototype.slice.call(mutation.removedNodes);
|
||||
var allNodes = addedNodes.concat(removedNodes);
|
||||
|
||||
if (containsAOSNode(allNodes)) {
|
||||
return callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getMutationObserver() {
|
||||
return window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
|
||||
}
|
||||
|
||||
function isSupported() {
|
||||
return !!getMutationObserver();
|
||||
}
|
||||
|
||||
function ready(selector, fn) {
|
||||
var doc = window.document;
|
||||
var MutationObserver = getMutationObserver();
|
||||
|
||||
var observer = new MutationObserver(check);
|
||||
callback = fn;
|
||||
|
||||
observer.observe(doc.documentElement, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
removedNodes: true
|
||||
});
|
||||
}
|
||||
|
||||
var observer = { isSupported: isSupported, ready: ready };
|
||||
|
||||
var classCallCheck = function (instance, Constructor) {
|
||||
if (!(instance instanceof Constructor)) {
|
||||
throw new TypeError("Cannot call a class as a function");
|
||||
}
|
||||
};
|
||||
|
||||
var createClass = function () {
|
||||
function defineProperties(target, props) {
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
var descriptor = props[i];
|
||||
descriptor.enumerable = descriptor.enumerable || false;
|
||||
descriptor.configurable = true;
|
||||
if ("value" in descriptor) descriptor.writable = true;
|
||||
Object.defineProperty(target, descriptor.key, descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
return function (Constructor, protoProps, staticProps) {
|
||||
if (protoProps) defineProperties(Constructor.prototype, protoProps);
|
||||
if (staticProps) defineProperties(Constructor, staticProps);
|
||||
return Constructor;
|
||||
};
|
||||
}();
|
||||
|
||||
var _extends = Object.assign || function (target) {
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
var source = arguments[i];
|
||||
|
||||
for (var key in source) {
|
||||
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
};
|
||||
|
||||
/**
|
||||
* Device detector
|
||||
*/
|
||||
|
||||
var fullNameRe = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i;
|
||||
var prefixRe = /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i;
|
||||
var fullNameMobileRe = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i;
|
||||
var prefixMobileRe = /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i;
|
||||
|
||||
function ua() {
|
||||
return navigator.userAgent || navigator.vendor || window.opera || '';
|
||||
}
|
||||
|
||||
var Detector = function () {
|
||||
function Detector() {
|
||||
classCallCheck(this, Detector);
|
||||
}
|
||||
|
||||
createClass(Detector, [{
|
||||
key: 'phone',
|
||||
value: function phone() {
|
||||
var a = ua();
|
||||
return !!(fullNameRe.test(a) || prefixRe.test(a.substr(0, 4)));
|
||||
}
|
||||
}, {
|
||||
key: 'mobile',
|
||||
value: function mobile() {
|
||||
var a = ua();
|
||||
return !!(fullNameMobileRe.test(a) || prefixMobileRe.test(a.substr(0, 4)));
|
||||
}
|
||||
}, {
|
||||
key: 'tablet',
|
||||
value: function tablet() {
|
||||
return this.mobile() && !this.phone();
|
||||
}
|
||||
|
||||
// http://browserhacks.com/#hack-acea075d0ac6954f275a70023906050c
|
||||
|
||||
}, {
|
||||
key: 'ie11',
|
||||
value: function ie11() {
|
||||
return '-ms-scroll-limit' in document.documentElement.style && '-ms-ime-align' in document.documentElement.style;
|
||||
}
|
||||
}]);
|
||||
return Detector;
|
||||
}();
|
||||
|
||||
var detect = new Detector();
|
||||
|
||||
/**
|
||||
* Adds multiple classes on node
|
||||
* @param {DOMNode} node
|
||||
* @param {array} classes
|
||||
*/
|
||||
var addClasses = function addClasses(node, classes) {
|
||||
return classes && classes.forEach(function (className) {
|
||||
return node.classList.add(className);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes multiple classes from node
|
||||
* @param {DOMNode} node
|
||||
* @param {array} classes
|
||||
*/
|
||||
var removeClasses = function removeClasses(node, classes) {
|
||||
return classes && classes.forEach(function (className) {
|
||||
return node.classList.remove(className);
|
||||
});
|
||||
};
|
||||
|
||||
var fireEvent = function fireEvent(eventName, data) {
|
||||
var customEvent = void 0;
|
||||
|
||||
if (detect.ie11()) {
|
||||
customEvent = document.createEvent('CustomEvent');
|
||||
customEvent.initCustomEvent(eventName, true, true, { detail: data });
|
||||
} else {
|
||||
customEvent = new CustomEvent(eventName, {
|
||||
detail: data
|
||||
});
|
||||
}
|
||||
|
||||
return document.dispatchEvent(customEvent);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set or remove aos-animate class
|
||||
* @param {node} el element
|
||||
* @param {int} top scrolled distance
|
||||
*/
|
||||
var applyClasses = function applyClasses(el, top) {
|
||||
var options = el.options,
|
||||
position = el.position,
|
||||
node = el.node,
|
||||
data = el.data;
|
||||
|
||||
|
||||
var hide = function hide() {
|
||||
if (!el.animated) return;
|
||||
|
||||
removeClasses(node, options.animatedClassNames);
|
||||
fireEvent('aos:out', node);
|
||||
|
||||
if (el.options.id) {
|
||||
fireEvent('aos:in:' + el.options.id, node);
|
||||
}
|
||||
|
||||
el.animated = false;
|
||||
};
|
||||
|
||||
var show = function show() {
|
||||
if (el.animated) return;
|
||||
|
||||
addClasses(node, options.animatedClassNames);
|
||||
|
||||
fireEvent('aos:in', node);
|
||||
if (el.options.id) {
|
||||
fireEvent('aos:in:' + el.options.id, node);
|
||||
}
|
||||
|
||||
el.animated = true;
|
||||
};
|
||||
|
||||
if (options.mirror && top >= position.out && !options.once) {
|
||||
hide();
|
||||
} else if (top >= position.in) {
|
||||
show();
|
||||
} else if (el.animated && !options.once) {
|
||||
hide();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Scroll logic - add or remove 'aos-animate' class on scroll
|
||||
*
|
||||
* @param {array} $elements array of elements nodes
|
||||
* @return {void}
|
||||
*/
|
||||
var handleScroll = function handleScroll($elements) {
|
||||
return $elements.forEach(function (el, i) {
|
||||
return applyClasses(el, window.pageYOffset);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get offset of DOM element
|
||||
* like there were no transforms applied on it
|
||||
*
|
||||
* @param {Node} el [DOM element]
|
||||
* @return {Object} [top and left offset]
|
||||
*/
|
||||
var offset = function offset(el) {
|
||||
var _x = 0;
|
||||
var _y = 0;
|
||||
|
||||
while (el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) {
|
||||
_x += el.offsetLeft - (el.tagName != 'BODY' ? el.scrollLeft : 0);
|
||||
_y += el.offsetTop - (el.tagName != 'BODY' ? el.scrollTop : 0);
|
||||
el = el.offsetParent;
|
||||
}
|
||||
|
||||
return {
|
||||
top: _y,
|
||||
left: _x
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Get inline option with a fallback.
|
||||
*
|
||||
* @param {Node} el [Dom element]
|
||||
* @param {String} key [Option key]
|
||||
* @param {String} fallback [Default (fallback) value]
|
||||
* @return {Mixed} [Option set with inline attributes or fallback value if not set]
|
||||
*/
|
||||
|
||||
var getInlineOption = (function (el, key, fallback) {
|
||||
var attr = el.getAttribute('data-aos-' + key);
|
||||
|
||||
if (typeof attr !== 'undefined') {
|
||||
if (attr === 'true') {
|
||||
return true;
|
||||
} else if (attr === 'false') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return attr || fallback;
|
||||
});
|
||||
|
||||
/**
|
||||
* Calculate offset
|
||||
* basing on element's settings like:
|
||||
* - anchor
|
||||
* - offset
|
||||
*
|
||||
* @param {Node} el [Dom element]
|
||||
* @return {Integer} [Final offset that will be used to trigger animation in good position]
|
||||
*/
|
||||
|
||||
var getPositionIn = function getPositionIn(el, defaultOffset, defaultAnchorPlacement) {
|
||||
var windowHeight = window.innerHeight;
|
||||
var anchor = getInlineOption(el, 'anchor');
|
||||
var inlineAnchorPlacement = getInlineOption(el, 'anchor-placement');
|
||||
var additionalOffset = Number(getInlineOption(el, 'offset', inlineAnchorPlacement ? 0 : defaultOffset));
|
||||
var anchorPlacement = inlineAnchorPlacement || defaultAnchorPlacement;
|
||||
var finalEl = el;
|
||||
|
||||
if (anchor && document.querySelectorAll(anchor)) {
|
||||
finalEl = document.querySelectorAll(anchor)[0];
|
||||
}
|
||||
|
||||
var triggerPoint = offset(finalEl).top - windowHeight;
|
||||
|
||||
switch (anchorPlacement) {
|
||||
case 'top-bottom':
|
||||
// Default offset
|
||||
break;
|
||||
case 'center-bottom':
|
||||
triggerPoint += finalEl.offsetHeight / 2;
|
||||
break;
|
||||
case 'bottom-bottom':
|
||||
triggerPoint += finalEl.offsetHeight;
|
||||
break;
|
||||
case 'top-center':
|
||||
triggerPoint += windowHeight / 2;
|
||||
break;
|
||||
case 'center-center':
|
||||
triggerPoint += windowHeight / 2 + finalEl.offsetHeight / 2;
|
||||
break;
|
||||
case 'bottom-center':
|
||||
triggerPoint += windowHeight / 2 + finalEl.offsetHeight;
|
||||
break;
|
||||
case 'top-top':
|
||||
triggerPoint += windowHeight;
|
||||
break;
|
||||
case 'bottom-top':
|
||||
triggerPoint += windowHeight + finalEl.offsetHeight;
|
||||
break;
|
||||
case 'center-top':
|
||||
triggerPoint += windowHeight + finalEl.offsetHeight / 2;
|
||||
break;
|
||||
}
|
||||
|
||||
return triggerPoint + additionalOffset;
|
||||
};
|
||||
|
||||
var getPositionOut = function getPositionOut(el, defaultOffset) {
|
||||
var windowHeight = window.innerHeight;
|
||||
var anchor = getInlineOption(el, 'anchor');
|
||||
var additionalOffset = getInlineOption(el, 'offset', defaultOffset);
|
||||
var finalEl = el;
|
||||
|
||||
if (anchor && document.querySelectorAll(anchor)) {
|
||||
finalEl = document.querySelectorAll(anchor)[0];
|
||||
}
|
||||
|
||||
var elementOffsetTop = offset(finalEl).top;
|
||||
|
||||
return elementOffsetTop + finalEl.offsetHeight - additionalOffset;
|
||||
};
|
||||
|
||||
/* Clearing variables */
|
||||
|
||||
var prepare = function prepare($elements, options) {
|
||||
$elements.forEach(function (el, i) {
|
||||
var mirror = getInlineOption(el.node, 'mirror', options.mirror);
|
||||
var once = getInlineOption(el.node, 'once', options.once);
|
||||
var id = getInlineOption(el.node, 'id');
|
||||
var customClassNames = options.useClassNames && el.node.getAttribute('data-aos');
|
||||
|
||||
var animatedClassNames = [options.animatedClassName].concat(customClassNames ? customClassNames.split(' ') : []).filter(function (className) {
|
||||
return typeof className === 'string';
|
||||
});
|
||||
|
||||
if (options.initClassName) {
|
||||
el.node.classList.add(options.initClassName);
|
||||
}
|
||||
|
||||
el.position = {
|
||||
in: getPositionIn(el.node, options.offset, options.anchorPlacement),
|
||||
out: mirror && getPositionOut(el.node, options.offset)
|
||||
};
|
||||
|
||||
el.options = {
|
||||
once: once,
|
||||
mirror: mirror,
|
||||
animatedClassNames: animatedClassNames,
|
||||
id: id
|
||||
};
|
||||
});
|
||||
|
||||
return $elements;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate initial array with elements as objects
|
||||
* This array will be extended later with elements attributes values
|
||||
* like 'position'
|
||||
*/
|
||||
var elements = (function () {
|
||||
var elements = document.querySelectorAll('[data-aos]');
|
||||
return Array.prototype.map.call(elements, function (node) {
|
||||
return { node: node };
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* *******************************************************
|
||||
* AOS (Animate on scroll) - wowjs alternative
|
||||
* made to animate elements on scroll in both directions
|
||||
* *******************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
* Private variables
|
||||
*/
|
||||
var $aosElements = [];
|
||||
var initialized = false;
|
||||
|
||||
/**
|
||||
* Default options
|
||||
*/
|
||||
var options = {
|
||||
offset: 120,
|
||||
delay: 0,
|
||||
easing: 'ease',
|
||||
duration: 400,
|
||||
disable: false,
|
||||
once: false,
|
||||
mirror: false,
|
||||
anchorPlacement: 'top-bottom',
|
||||
startEvent: 'DOMContentLoaded',
|
||||
animatedClassName: 'aos-animate',
|
||||
initClassName: 'aos-init',
|
||||
useClassNames: false,
|
||||
disableMutationObserver: false,
|
||||
throttleDelay: 99,
|
||||
debounceDelay: 50
|
||||
};
|
||||
|
||||
// Detect not supported browsers (<=IE9)
|
||||
// http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805
|
||||
var isBrowserNotSupported = function isBrowserNotSupported() {
|
||||
return document.all && !window.atob;
|
||||
};
|
||||
|
||||
var initializeScroll = function initializeScroll() {
|
||||
// Extend elements objects in $aosElements with their positions
|
||||
$aosElements = prepare($aosElements, options);
|
||||
// Perform scroll event, to refresh view and show/hide elements
|
||||
handleScroll($aosElements);
|
||||
|
||||
/**
|
||||
* Handle scroll event to animate elements on scroll
|
||||
*/
|
||||
window.addEventListener('scroll', throttle(function () {
|
||||
handleScroll($aosElements, options.once);
|
||||
}, options.throttleDelay));
|
||||
|
||||
return $aosElements;
|
||||
};
|
||||
|
||||
/**
|
||||
* Refresh AOS
|
||||
*/
|
||||
var refresh = function refresh() {
|
||||
var initialize = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
||||
|
||||
// Allow refresh only when it was first initialized on startEvent
|
||||
if (initialize) initialized = true;
|
||||
if (initialized) initializeScroll();
|
||||
};
|
||||
|
||||
/**
|
||||
* Hard refresh
|
||||
* create array with new elements and trigger refresh
|
||||
*/
|
||||
var refreshHard = function refreshHard() {
|
||||
$aosElements = elements();
|
||||
|
||||
if (isDisabled(options.disable) || isBrowserNotSupported()) {
|
||||
return disable();
|
||||
}
|
||||
|
||||
refresh();
|
||||
};
|
||||
|
||||
/**
|
||||
* Disable AOS
|
||||
* Remove all attributes to reset applied styles
|
||||
*/
|
||||
var disable = function disable() {
|
||||
$aosElements.forEach(function (el, i) {
|
||||
el.node.removeAttribute('data-aos');
|
||||
el.node.removeAttribute('data-aos-easing');
|
||||
el.node.removeAttribute('data-aos-duration');
|
||||
el.node.removeAttribute('data-aos-delay');
|
||||
|
||||
if (options.initClassName) {
|
||||
el.node.classList.remove(options.initClassName);
|
||||
}
|
||||
|
||||
if (options.animatedClassName) {
|
||||
el.node.classList.remove(options.animatedClassName);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if AOS should be disabled based on provided setting
|
||||
*/
|
||||
var isDisabled = function isDisabled(optionDisable) {
|
||||
return optionDisable === true || optionDisable === 'mobile' && detect.mobile() || optionDisable === 'phone' && detect.phone() || optionDisable === 'tablet' && detect.tablet() || typeof optionDisable === 'function' && optionDisable() === true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializing AOS
|
||||
* - Create options merging defaults with user defined options
|
||||
* - Set attributes on <body> as global setting - css relies on it
|
||||
* - Attach preparing elements to options.startEvent,
|
||||
* window resize and orientation change
|
||||
* - Attach function that handle scroll and everything connected to it
|
||||
* to window scroll event and fire once document is ready to set initial state
|
||||
*/
|
||||
var init = function init(settings) {
|
||||
options = _extends(options, settings);
|
||||
|
||||
// Create initial array with elements -> to be fullfilled later with prepare()
|
||||
$aosElements = elements();
|
||||
|
||||
/**
|
||||
* Disable mutation observing if not supported
|
||||
*/
|
||||
if (!options.disableMutationObserver && !observer.isSupported()) {
|
||||
console.info('\n aos: MutationObserver is not supported on this browser,\n code mutations observing has been disabled.\n You may have to call "refreshHard()" by yourself.\n ');
|
||||
options.disableMutationObserver = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Observe [aos] elements
|
||||
* If something is loaded by AJAX
|
||||
* it'll refresh plugin automatically
|
||||
*/
|
||||
if (!options.disableMutationObserver) {
|
||||
observer.ready('[data-aos]', refreshHard);
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't init plugin if option `disable` is set
|
||||
* or when browser is not supported
|
||||
*/
|
||||
if (isDisabled(options.disable) || isBrowserNotSupported()) {
|
||||
return disable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set global settings on body, based on options
|
||||
* so CSS can use it
|
||||
*/
|
||||
document.querySelector('body').setAttribute('data-aos-easing', options.easing);
|
||||
|
||||
document.querySelector('body').setAttribute('data-aos-duration', options.duration);
|
||||
|
||||
document.querySelector('body').setAttribute('data-aos-delay', options.delay);
|
||||
|
||||
/**
|
||||
* Handle initializing
|
||||
*/
|
||||
if (['DOMContentLoaded', 'load'].indexOf(options.startEvent) === -1) {
|
||||
// Listen to options.startEvent and initialize AOS
|
||||
document.addEventListener(options.startEvent, function () {
|
||||
refresh(true);
|
||||
});
|
||||
} else {
|
||||
window.addEventListener('load', function () {
|
||||
refresh(true);
|
||||
});
|
||||
}
|
||||
|
||||
if (options.startEvent === 'DOMContentLoaded' && ['complete', 'interactive'].indexOf(document.readyState) > -1) {
|
||||
// Initialize AOS if default startEvent was already fired
|
||||
refresh(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh plugin on window resize or orientation change
|
||||
*/
|
||||
window.addEventListener('resize', debounce(refresh, options.debounceDelay, true));
|
||||
|
||||
window.addEventListener('orientationchange', debounce(refresh, options.debounceDelay, true));
|
||||
|
||||
return $aosElements;
|
||||
};
|
||||
|
||||
/**
|
||||
* Export Public API
|
||||
*/
|
||||
|
||||
var aos = {
|
||||
init: init,
|
||||
refresh: refresh,
|
||||
refreshHard: refreshHard
|
||||
};
|
||||
|
||||
export default aos;
|
||||
1
HealthOneProject/assets/vendor/aos/aos.js
vendored
Normal file
1
HealthOneProject/assets/vendor/aos/aos.js.map
vendored
Normal file
2106
HealthOneProject/assets/vendor/bootstrap-icons/bootstrap-icons.css
vendored
Normal file
2080
HealthOneProject/assets/vendor/bootstrap-icons/bootstrap-icons.json
vendored
Normal file
5
HealthOneProject/assets/vendor/bootstrap-icons/bootstrap-icons.min.css
vendored
Normal file
2118
HealthOneProject/assets/vendor/bootstrap-icons/bootstrap-icons.scss
vendored
Normal file
BIN
HealthOneProject/assets/vendor/bootstrap-icons/fonts/bootstrap-icons.woff
vendored
Normal file
BIN
HealthOneProject/assets/vendor/bootstrap-icons/fonts/bootstrap-icons.woff2
vendored
Normal file
4085
HealthOneProject/assets/vendor/bootstrap/css/bootstrap-grid.css
vendored
Normal file
1
HealthOneProject/assets/vendor/bootstrap/css/bootstrap-grid.css.map
vendored
Normal file
6
HealthOneProject/assets/vendor/bootstrap/css/bootstrap-grid.min.css
vendored
Normal file
1
HealthOneProject/assets/vendor/bootstrap/css/bootstrap-grid.min.css.map
vendored
Normal file
4084
HealthOneProject/assets/vendor/bootstrap/css/bootstrap-grid.rtl.css
vendored
Normal file
1
HealthOneProject/assets/vendor/bootstrap/css/bootstrap-grid.rtl.css.map
vendored
Normal file
6
HealthOneProject/assets/vendor/bootstrap/css/bootstrap-grid.rtl.min.css
vendored
Normal file
1
HealthOneProject/assets/vendor/bootstrap/css/bootstrap-grid.rtl.min.css.map
vendored
Normal file
601
HealthOneProject/assets/vendor/bootstrap/css/bootstrap-reboot.css
vendored
Normal file
@ -0,0 +1,601 @@
|
||||
/*!
|
||||
* Bootstrap Reboot v5.3.8 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2025 The Bootstrap Authors
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
:root,
|
||||
[data-bs-theme=light] {
|
||||
--bs-blue: #0d6efd;
|
||||
--bs-indigo: #6610f2;
|
||||
--bs-purple: #6f42c1;
|
||||
--bs-pink: #d63384;
|
||||
--bs-red: #dc3545;
|
||||
--bs-orange: #fd7e14;
|
||||
--bs-yellow: #ffc107;
|
||||
--bs-green: #198754;
|
||||
--bs-teal: #20c997;
|
||||
--bs-cyan: #0dcaf0;
|
||||
--bs-black: #000;
|
||||
--bs-white: #fff;
|
||||
--bs-gray: #6c757d;
|
||||
--bs-gray-dark: #343a40;
|
||||
--bs-gray-100: #f8f9fa;
|
||||
--bs-gray-200: #e9ecef;
|
||||
--bs-gray-300: #dee2e6;
|
||||
--bs-gray-400: #ced4da;
|
||||
--bs-gray-500: #adb5bd;
|
||||
--bs-gray-600: #6c757d;
|
||||
--bs-gray-700: #495057;
|
||||
--bs-gray-800: #343a40;
|
||||
--bs-gray-900: #212529;
|
||||
--bs-primary: #0d6efd;
|
||||
--bs-secondary: #6c757d;
|
||||
--bs-success: #198754;
|
||||
--bs-info: #0dcaf0;
|
||||
--bs-warning: #ffc107;
|
||||
--bs-danger: #dc3545;
|
||||
--bs-light: #f8f9fa;
|
||||
--bs-dark: #212529;
|
||||
--bs-primary-rgb: 13, 110, 253;
|
||||
--bs-secondary-rgb: 108, 117, 125;
|
||||
--bs-success-rgb: 25, 135, 84;
|
||||
--bs-info-rgb: 13, 202, 240;
|
||||
--bs-warning-rgb: 255, 193, 7;
|
||||
--bs-danger-rgb: 220, 53, 69;
|
||||
--bs-light-rgb: 248, 249, 250;
|
||||
--bs-dark-rgb: 33, 37, 41;
|
||||
--bs-primary-text-emphasis: #052c65;
|
||||
--bs-secondary-text-emphasis: #2b2f32;
|
||||
--bs-success-text-emphasis: #0a3622;
|
||||
--bs-info-text-emphasis: #055160;
|
||||
--bs-warning-text-emphasis: #664d03;
|
||||
--bs-danger-text-emphasis: #58151c;
|
||||
--bs-light-text-emphasis: #495057;
|
||||
--bs-dark-text-emphasis: #495057;
|
||||
--bs-primary-bg-subtle: #cfe2ff;
|
||||
--bs-secondary-bg-subtle: #e2e3e5;
|
||||
--bs-success-bg-subtle: #d1e7dd;
|
||||
--bs-info-bg-subtle: #cff4fc;
|
||||
--bs-warning-bg-subtle: #fff3cd;
|
||||
--bs-danger-bg-subtle: #f8d7da;
|
||||
--bs-light-bg-subtle: #fcfcfd;
|
||||
--bs-dark-bg-subtle: #ced4da;
|
||||
--bs-primary-border-subtle: #9ec5fe;
|
||||
--bs-secondary-border-subtle: #c4c8cb;
|
||||
--bs-success-border-subtle: #a3cfbb;
|
||||
--bs-info-border-subtle: #9eeaf9;
|
||||
--bs-warning-border-subtle: #ffe69c;
|
||||
--bs-danger-border-subtle: #f1aeb5;
|
||||
--bs-light-border-subtle: #e9ecef;
|
||||
--bs-dark-border-subtle: #adb5bd;
|
||||
--bs-white-rgb: 255, 255, 255;
|
||||
--bs-black-rgb: 0, 0, 0;
|
||||
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
||||
--bs-body-font-family: var(--bs-font-sans-serif);
|
||||
--bs-body-font-size: 1rem;
|
||||
--bs-body-font-weight: 400;
|
||||
--bs-body-line-height: 1.5;
|
||||
--bs-body-color: #212529;
|
||||
--bs-body-color-rgb: 33, 37, 41;
|
||||
--bs-body-bg: #fff;
|
||||
--bs-body-bg-rgb: 255, 255, 255;
|
||||
--bs-emphasis-color: #000;
|
||||
--bs-emphasis-color-rgb: 0, 0, 0;
|
||||
--bs-secondary-color: rgba(33, 37, 41, 0.75);
|
||||
--bs-secondary-color-rgb: 33, 37, 41;
|
||||
--bs-secondary-bg: #e9ecef;
|
||||
--bs-secondary-bg-rgb: 233, 236, 239;
|
||||
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
|
||||
--bs-tertiary-color-rgb: 33, 37, 41;
|
||||
--bs-tertiary-bg: #f8f9fa;
|
||||
--bs-tertiary-bg-rgb: 248, 249, 250;
|
||||
--bs-heading-color: inherit;
|
||||
--bs-link-color: #0d6efd;
|
||||
--bs-link-color-rgb: 13, 110, 253;
|
||||
--bs-link-decoration: underline;
|
||||
--bs-link-hover-color: #0a58ca;
|
||||
--bs-link-hover-color-rgb: 10, 88, 202;
|
||||
--bs-code-color: #d63384;
|
||||
--bs-highlight-color: #212529;
|
||||
--bs-highlight-bg: #fff3cd;
|
||||
--bs-border-width: 1px;
|
||||
--bs-border-style: solid;
|
||||
--bs-border-color: #dee2e6;
|
||||
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
|
||||
--bs-border-radius: 0.375rem;
|
||||
--bs-border-radius-sm: 0.25rem;
|
||||
--bs-border-radius-lg: 0.5rem;
|
||||
--bs-border-radius-xl: 1rem;
|
||||
--bs-border-radius-xxl: 2rem;
|
||||
--bs-border-radius-2xl: var(--bs-border-radius-xxl);
|
||||
--bs-border-radius-pill: 50rem;
|
||||
--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
||||
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
||||
--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
|
||||
--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
|
||||
--bs-focus-ring-width: 0.25rem;
|
||||
--bs-focus-ring-opacity: 0.25;
|
||||
--bs-focus-ring-color: rgba(13, 110, 253, 0.25);
|
||||
--bs-form-valid-color: #198754;
|
||||
--bs-form-valid-border-color: #198754;
|
||||
--bs-form-invalid-color: #dc3545;
|
||||
--bs-form-invalid-border-color: #dc3545;
|
||||
}
|
||||
|
||||
[data-bs-theme=dark] {
|
||||
color-scheme: dark;
|
||||
--bs-body-color: #dee2e6;
|
||||
--bs-body-color-rgb: 222, 226, 230;
|
||||
--bs-body-bg: #212529;
|
||||
--bs-body-bg-rgb: 33, 37, 41;
|
||||
--bs-emphasis-color: #fff;
|
||||
--bs-emphasis-color-rgb: 255, 255, 255;
|
||||
--bs-secondary-color: rgba(222, 226, 230, 0.75);
|
||||
--bs-secondary-color-rgb: 222, 226, 230;
|
||||
--bs-secondary-bg: #343a40;
|
||||
--bs-secondary-bg-rgb: 52, 58, 64;
|
||||
--bs-tertiary-color: rgba(222, 226, 230, 0.5);
|
||||
--bs-tertiary-color-rgb: 222, 226, 230;
|
||||
--bs-tertiary-bg: #2b3035;
|
||||
--bs-tertiary-bg-rgb: 43, 48, 53;
|
||||
--bs-primary-text-emphasis: #6ea8fe;
|
||||
--bs-secondary-text-emphasis: #a7acb1;
|
||||
--bs-success-text-emphasis: #75b798;
|
||||
--bs-info-text-emphasis: #6edff6;
|
||||
--bs-warning-text-emphasis: #ffda6a;
|
||||
--bs-danger-text-emphasis: #ea868f;
|
||||
--bs-light-text-emphasis: #f8f9fa;
|
||||
--bs-dark-text-emphasis: #dee2e6;
|
||||
--bs-primary-bg-subtle: #031633;
|
||||
--bs-secondary-bg-subtle: #161719;
|
||||
--bs-success-bg-subtle: #051b11;
|
||||
--bs-info-bg-subtle: #032830;
|
||||
--bs-warning-bg-subtle: #332701;
|
||||
--bs-danger-bg-subtle: #2c0b0e;
|
||||
--bs-light-bg-subtle: #343a40;
|
||||
--bs-dark-bg-subtle: #1a1d20;
|
||||
--bs-primary-border-subtle: #084298;
|
||||
--bs-secondary-border-subtle: #41464b;
|
||||
--bs-success-border-subtle: #0f5132;
|
||||
--bs-info-border-subtle: #087990;
|
||||
--bs-warning-border-subtle: #997404;
|
||||
--bs-danger-border-subtle: #842029;
|
||||
--bs-light-border-subtle: #495057;
|
||||
--bs-dark-border-subtle: #343a40;
|
||||
--bs-heading-color: inherit;
|
||||
--bs-link-color: #6ea8fe;
|
||||
--bs-link-hover-color: #8bb9fe;
|
||||
--bs-link-color-rgb: 110, 168, 254;
|
||||
--bs-link-hover-color-rgb: 139, 185, 254;
|
||||
--bs-code-color: #e685b5;
|
||||
--bs-highlight-color: #dee2e6;
|
||||
--bs-highlight-bg: #664d03;
|
||||
--bs-border-color: #495057;
|
||||
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
|
||||
--bs-form-valid-color: #75b798;
|
||||
--bs-form-valid-border-color: #75b798;
|
||||
--bs-form-invalid-color: #ea868f;
|
||||
--bs-form-invalid-border-color: #ea868f;
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
:root {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: var(--bs-body-font-family);
|
||||
font-size: var(--bs-body-font-size);
|
||||
font-weight: var(--bs-body-font-weight);
|
||||
line-height: var(--bs-body-line-height);
|
||||
color: var(--bs-body-color);
|
||||
text-align: var(--bs-body-text-align);
|
||||
background-color: var(--bs-body-bg);
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 1rem 0;
|
||||
color: inherit;
|
||||
border: 0;
|
||||
border-top: var(--bs-border-width) solid;
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
h6, h5, h4, h3, h2, h1 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 500;
|
||||
line-height: 1.2;
|
||||
color: var(--bs-heading-color);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: calc(1.375rem + 1.5vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: calc(1.325rem + 0.9vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h2 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: calc(1.3rem + 0.6vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h3 {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h4 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
abbr[title] {
|
||||
-webkit-text-decoration: underline dotted;
|
||||
text-decoration: underline dotted;
|
||||
cursor: help;
|
||||
-webkit-text-decoration-skip-ink: none;
|
||||
text-decoration-skip-ink: none;
|
||||
}
|
||||
|
||||
address {
|
||||
margin-bottom: 1rem;
|
||||
font-style: normal;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul {
|
||||
padding-left: 2rem;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
dl {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
ol ol,
|
||||
ul ul,
|
||||
ol ul,
|
||||
ul ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: 0.5rem;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
mark {
|
||||
padding: 0.1875em;
|
||||
color: var(--bs-highlight-color);
|
||||
background-color: var(--bs-highlight-bg);
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
position: relative;
|
||||
font-size: 0.75em;
|
||||
line-height: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
|
||||
text-decoration: underline;
|
||||
}
|
||||
a:hover {
|
||||
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
|
||||
}
|
||||
|
||||
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
pre,
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: var(--bs-font-monospace);
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
pre {
|
||||
display: block;
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
overflow: auto;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
pre code {
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 0.875em;
|
||||
color: var(--bs-code-color);
|
||||
word-wrap: break-word;
|
||||
}
|
||||
a > code {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
kbd {
|
||||
padding: 0.1875rem 0.375rem;
|
||||
font-size: 0.875em;
|
||||
color: var(--bs-body-bg);
|
||||
background-color: var(--bs-body-color);
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
kbd kbd {
|
||||
padding: 0;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
img,
|
||||
svg {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
table {
|
||||
caption-side: bottom;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
caption {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
color: var(--bs-secondary-color);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: inherit;
|
||||
text-align: -webkit-match-parent;
|
||||
}
|
||||
|
||||
thead,
|
||||
tbody,
|
||||
tfoot,
|
||||
tr,
|
||||
td,
|
||||
th {
|
||||
border-color: inherit;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
button:focus:not(:focus-visible) {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
optgroup,
|
||||
textarea {
|
||||
margin: 0;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
[role=button] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
select {
|
||||
word-wrap: normal;
|
||||
}
|
||||
select:disabled {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
button,
|
||||
[type=button],
|
||||
[type=reset],
|
||||
[type=submit] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
button:not(:disabled),
|
||||
[type=button]:not(:disabled),
|
||||
[type=reset]:not(:disabled),
|
||||
[type=submit]:not(:disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
float: left;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
line-height: inherit;
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
legend {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
legend + * {
|
||||
clear: left;
|
||||
}
|
||||
|
||||
::-webkit-datetime-edit-fields-wrapper,
|
||||
::-webkit-datetime-edit-text,
|
||||
::-webkit-datetime-edit-minute,
|
||||
::-webkit-datetime-edit-hour-field,
|
||||
::-webkit-datetime-edit-day-field,
|
||||
::-webkit-datetime-edit-month-field,
|
||||
::-webkit-datetime-edit-year-field {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::-webkit-inner-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
[type=search] {
|
||||
-webkit-appearance: textfield;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
[type=search]::-webkit-search-cancel-button {
|
||||
cursor: pointer;
|
||||
filter: grayscale(1);
|
||||
}
|
||||
|
||||
/* rtl:raw:
|
||||
[type="tel"],
|
||||
[type="url"],
|
||||
[type="email"],
|
||||
[type="number"] {
|
||||
direction: ltr;
|
||||
}
|
||||
*/
|
||||
::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
::-webkit-color-swatch-wrapper {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
::file-selector-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
output {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
iframe {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=bootstrap-reboot.css.map */
|
||||
1
HealthOneProject/assets/vendor/bootstrap/css/bootstrap-reboot.css.map
vendored
Normal file
6
HealthOneProject/assets/vendor/bootstrap/css/bootstrap-reboot.min.css
vendored
Normal file
1
HealthOneProject/assets/vendor/bootstrap/css/bootstrap-reboot.min.css.map
vendored
Normal file
598
HealthOneProject/assets/vendor/bootstrap/css/bootstrap-reboot.rtl.css
vendored
Normal file
@ -0,0 +1,598 @@
|
||||
/*!
|
||||
* Bootstrap Reboot v5.3.8 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2025 The Bootstrap Authors
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
:root,
|
||||
[data-bs-theme=light] {
|
||||
--bs-blue: #0d6efd;
|
||||
--bs-indigo: #6610f2;
|
||||
--bs-purple: #6f42c1;
|
||||
--bs-pink: #d63384;
|
||||
--bs-red: #dc3545;
|
||||
--bs-orange: #fd7e14;
|
||||
--bs-yellow: #ffc107;
|
||||
--bs-green: #198754;
|
||||
--bs-teal: #20c997;
|
||||
--bs-cyan: #0dcaf0;
|
||||
--bs-black: #000;
|
||||
--bs-white: #fff;
|
||||
--bs-gray: #6c757d;
|
||||
--bs-gray-dark: #343a40;
|
||||
--bs-gray-100: #f8f9fa;
|
||||
--bs-gray-200: #e9ecef;
|
||||
--bs-gray-300: #dee2e6;
|
||||
--bs-gray-400: #ced4da;
|
||||
--bs-gray-500: #adb5bd;
|
||||
--bs-gray-600: #6c757d;
|
||||
--bs-gray-700: #495057;
|
||||
--bs-gray-800: #343a40;
|
||||
--bs-gray-900: #212529;
|
||||
--bs-primary: #0d6efd;
|
||||
--bs-secondary: #6c757d;
|
||||
--bs-success: #198754;
|
||||
--bs-info: #0dcaf0;
|
||||
--bs-warning: #ffc107;
|
||||
--bs-danger: #dc3545;
|
||||
--bs-light: #f8f9fa;
|
||||
--bs-dark: #212529;
|
||||
--bs-primary-rgb: 13, 110, 253;
|
||||
--bs-secondary-rgb: 108, 117, 125;
|
||||
--bs-success-rgb: 25, 135, 84;
|
||||
--bs-info-rgb: 13, 202, 240;
|
||||
--bs-warning-rgb: 255, 193, 7;
|
||||
--bs-danger-rgb: 220, 53, 69;
|
||||
--bs-light-rgb: 248, 249, 250;
|
||||
--bs-dark-rgb: 33, 37, 41;
|
||||
--bs-primary-text-emphasis: #052c65;
|
||||
--bs-secondary-text-emphasis: #2b2f32;
|
||||
--bs-success-text-emphasis: #0a3622;
|
||||
--bs-info-text-emphasis: #055160;
|
||||
--bs-warning-text-emphasis: #664d03;
|
||||
--bs-danger-text-emphasis: #58151c;
|
||||
--bs-light-text-emphasis: #495057;
|
||||
--bs-dark-text-emphasis: #495057;
|
||||
--bs-primary-bg-subtle: #cfe2ff;
|
||||
--bs-secondary-bg-subtle: #e2e3e5;
|
||||
--bs-success-bg-subtle: #d1e7dd;
|
||||
--bs-info-bg-subtle: #cff4fc;
|
||||
--bs-warning-bg-subtle: #fff3cd;
|
||||
--bs-danger-bg-subtle: #f8d7da;
|
||||
--bs-light-bg-subtle: #fcfcfd;
|
||||
--bs-dark-bg-subtle: #ced4da;
|
||||
--bs-primary-border-subtle: #9ec5fe;
|
||||
--bs-secondary-border-subtle: #c4c8cb;
|
||||
--bs-success-border-subtle: #a3cfbb;
|
||||
--bs-info-border-subtle: #9eeaf9;
|
||||
--bs-warning-border-subtle: #ffe69c;
|
||||
--bs-danger-border-subtle: #f1aeb5;
|
||||
--bs-light-border-subtle: #e9ecef;
|
||||
--bs-dark-border-subtle: #adb5bd;
|
||||
--bs-white-rgb: 255, 255, 255;
|
||||
--bs-black-rgb: 0, 0, 0;
|
||||
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
||||
--bs-body-font-family: var(--bs-font-sans-serif);
|
||||
--bs-body-font-size: 1rem;
|
||||
--bs-body-font-weight: 400;
|
||||
--bs-body-line-height: 1.5;
|
||||
--bs-body-color: #212529;
|
||||
--bs-body-color-rgb: 33, 37, 41;
|
||||
--bs-body-bg: #fff;
|
||||
--bs-body-bg-rgb: 255, 255, 255;
|
||||
--bs-emphasis-color: #000;
|
||||
--bs-emphasis-color-rgb: 0, 0, 0;
|
||||
--bs-secondary-color: rgba(33, 37, 41, 0.75);
|
||||
--bs-secondary-color-rgb: 33, 37, 41;
|
||||
--bs-secondary-bg: #e9ecef;
|
||||
--bs-secondary-bg-rgb: 233, 236, 239;
|
||||
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
|
||||
--bs-tertiary-color-rgb: 33, 37, 41;
|
||||
--bs-tertiary-bg: #f8f9fa;
|
||||
--bs-tertiary-bg-rgb: 248, 249, 250;
|
||||
--bs-heading-color: inherit;
|
||||
--bs-link-color: #0d6efd;
|
||||
--bs-link-color-rgb: 13, 110, 253;
|
||||
--bs-link-decoration: underline;
|
||||
--bs-link-hover-color: #0a58ca;
|
||||
--bs-link-hover-color-rgb: 10, 88, 202;
|
||||
--bs-code-color: #d63384;
|
||||
--bs-highlight-color: #212529;
|
||||
--bs-highlight-bg: #fff3cd;
|
||||
--bs-border-width: 1px;
|
||||
--bs-border-style: solid;
|
||||
--bs-border-color: #dee2e6;
|
||||
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
|
||||
--bs-border-radius: 0.375rem;
|
||||
--bs-border-radius-sm: 0.25rem;
|
||||
--bs-border-radius-lg: 0.5rem;
|
||||
--bs-border-radius-xl: 1rem;
|
||||
--bs-border-radius-xxl: 2rem;
|
||||
--bs-border-radius-2xl: var(--bs-border-radius-xxl);
|
||||
--bs-border-radius-pill: 50rem;
|
||||
--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
||||
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
||||
--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
|
||||
--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
|
||||
--bs-focus-ring-width: 0.25rem;
|
||||
--bs-focus-ring-opacity: 0.25;
|
||||
--bs-focus-ring-color: rgba(13, 110, 253, 0.25);
|
||||
--bs-form-valid-color: #198754;
|
||||
--bs-form-valid-border-color: #198754;
|
||||
--bs-form-invalid-color: #dc3545;
|
||||
--bs-form-invalid-border-color: #dc3545;
|
||||
}
|
||||
|
||||
[data-bs-theme=dark] {
|
||||
color-scheme: dark;
|
||||
--bs-body-color: #dee2e6;
|
||||
--bs-body-color-rgb: 222, 226, 230;
|
||||
--bs-body-bg: #212529;
|
||||
--bs-body-bg-rgb: 33, 37, 41;
|
||||
--bs-emphasis-color: #fff;
|
||||
--bs-emphasis-color-rgb: 255, 255, 255;
|
||||
--bs-secondary-color: rgba(222, 226, 230, 0.75);
|
||||
--bs-secondary-color-rgb: 222, 226, 230;
|
||||
--bs-secondary-bg: #343a40;
|
||||
--bs-secondary-bg-rgb: 52, 58, 64;
|
||||
--bs-tertiary-color: rgba(222, 226, 230, 0.5);
|
||||
--bs-tertiary-color-rgb: 222, 226, 230;
|
||||
--bs-tertiary-bg: #2b3035;
|
||||
--bs-tertiary-bg-rgb: 43, 48, 53;
|
||||
--bs-primary-text-emphasis: #6ea8fe;
|
||||
--bs-secondary-text-emphasis: #a7acb1;
|
||||
--bs-success-text-emphasis: #75b798;
|
||||
--bs-info-text-emphasis: #6edff6;
|
||||
--bs-warning-text-emphasis: #ffda6a;
|
||||
--bs-danger-text-emphasis: #ea868f;
|
||||
--bs-light-text-emphasis: #f8f9fa;
|
||||
--bs-dark-text-emphasis: #dee2e6;
|
||||
--bs-primary-bg-subtle: #031633;
|
||||
--bs-secondary-bg-subtle: #161719;
|
||||
--bs-success-bg-subtle: #051b11;
|
||||
--bs-info-bg-subtle: #032830;
|
||||
--bs-warning-bg-subtle: #332701;
|
||||
--bs-danger-bg-subtle: #2c0b0e;
|
||||
--bs-light-bg-subtle: #343a40;
|
||||
--bs-dark-bg-subtle: #1a1d20;
|
||||
--bs-primary-border-subtle: #084298;
|
||||
--bs-secondary-border-subtle: #41464b;
|
||||
--bs-success-border-subtle: #0f5132;
|
||||
--bs-info-border-subtle: #087990;
|
||||
--bs-warning-border-subtle: #997404;
|
||||
--bs-danger-border-subtle: #842029;
|
||||
--bs-light-border-subtle: #495057;
|
||||
--bs-dark-border-subtle: #343a40;
|
||||
--bs-heading-color: inherit;
|
||||
--bs-link-color: #6ea8fe;
|
||||
--bs-link-hover-color: #8bb9fe;
|
||||
--bs-link-color-rgb: 110, 168, 254;
|
||||
--bs-link-hover-color-rgb: 139, 185, 254;
|
||||
--bs-code-color: #e685b5;
|
||||
--bs-highlight-color: #dee2e6;
|
||||
--bs-highlight-bg: #664d03;
|
||||
--bs-border-color: #495057;
|
||||
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
|
||||
--bs-form-valid-color: #75b798;
|
||||
--bs-form-valid-border-color: #75b798;
|
||||
--bs-form-invalid-color: #ea868f;
|
||||
--bs-form-invalid-border-color: #ea868f;
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
:root {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: var(--bs-body-font-family);
|
||||
font-size: var(--bs-body-font-size);
|
||||
font-weight: var(--bs-body-font-weight);
|
||||
line-height: var(--bs-body-line-height);
|
||||
color: var(--bs-body-color);
|
||||
text-align: var(--bs-body-text-align);
|
||||
background-color: var(--bs-body-bg);
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 1rem 0;
|
||||
color: inherit;
|
||||
border: 0;
|
||||
border-top: var(--bs-border-width) solid;
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
h6, h5, h4, h3, h2, h1 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 500;
|
||||
line-height: 1.2;
|
||||
color: var(--bs-heading-color);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: calc(1.375rem + 1.5vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: calc(1.325rem + 0.9vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h2 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: calc(1.3rem + 0.6vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h3 {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h4 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
abbr[title] {
|
||||
-webkit-text-decoration: underline dotted;
|
||||
text-decoration: underline dotted;
|
||||
cursor: help;
|
||||
-webkit-text-decoration-skip-ink: none;
|
||||
text-decoration-skip-ink: none;
|
||||
}
|
||||
|
||||
address {
|
||||
margin-bottom: 1rem;
|
||||
font-style: normal;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul {
|
||||
padding-right: 2rem;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
dl {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
ol ol,
|
||||
ul ul,
|
||||
ol ul,
|
||||
ul ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: 0.5rem;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
mark {
|
||||
padding: 0.1875em;
|
||||
color: var(--bs-highlight-color);
|
||||
background-color: var(--bs-highlight-bg);
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
position: relative;
|
||||
font-size: 0.75em;
|
||||
line-height: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
|
||||
text-decoration: underline;
|
||||
}
|
||||
a:hover {
|
||||
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
|
||||
}
|
||||
|
||||
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
pre,
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: var(--bs-font-monospace);
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
pre {
|
||||
display: block;
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
overflow: auto;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
pre code {
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 0.875em;
|
||||
color: var(--bs-code-color);
|
||||
word-wrap: break-word;
|
||||
}
|
||||
a > code {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
kbd {
|
||||
padding: 0.1875rem 0.375rem;
|
||||
font-size: 0.875em;
|
||||
color: var(--bs-body-bg);
|
||||
background-color: var(--bs-body-color);
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
kbd kbd {
|
||||
padding: 0;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
img,
|
||||
svg {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
table {
|
||||
caption-side: bottom;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
caption {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
color: var(--bs-secondary-color);
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: inherit;
|
||||
text-align: -webkit-match-parent;
|
||||
}
|
||||
|
||||
thead,
|
||||
tbody,
|
||||
tfoot,
|
||||
tr,
|
||||
td,
|
||||
th {
|
||||
border-color: inherit;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
button:focus:not(:focus-visible) {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
optgroup,
|
||||
textarea {
|
||||
margin: 0;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
[role=button] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
select {
|
||||
word-wrap: normal;
|
||||
}
|
||||
select:disabled {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
button,
|
||||
[type=button],
|
||||
[type=reset],
|
||||
[type=submit] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
button:not(:disabled),
|
||||
[type=button]:not(:disabled),
|
||||
[type=reset]:not(:disabled),
|
||||
[type=submit]:not(:disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
float: right;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
line-height: inherit;
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
legend {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
legend + * {
|
||||
clear: right;
|
||||
}
|
||||
|
||||
::-webkit-datetime-edit-fields-wrapper,
|
||||
::-webkit-datetime-edit-text,
|
||||
::-webkit-datetime-edit-minute,
|
||||
::-webkit-datetime-edit-hour-field,
|
||||
::-webkit-datetime-edit-day-field,
|
||||
::-webkit-datetime-edit-month-field,
|
||||
::-webkit-datetime-edit-year-field {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::-webkit-inner-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
[type=search] {
|
||||
-webkit-appearance: textfield;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
[type=search]::-webkit-search-cancel-button {
|
||||
cursor: pointer;
|
||||
filter: grayscale(1);
|
||||
}
|
||||
|
||||
[type="tel"],
|
||||
[type="url"],
|
||||
[type="email"],
|
||||
[type="number"] {
|
||||
direction: ltr;
|
||||
}
|
||||
::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
::-webkit-color-swatch-wrapper {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
::file-selector-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
output {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
iframe {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
/*# sourceMappingURL=bootstrap-reboot.rtl.css.map */
|
||||