frontend 1

This commit is contained in:
matt committed 2026-10-15 04:42:30 -07:00
1 parent 168c817324
commit 0bc92cdb8b
4 files changed
+148 -33

No files matched your search

+86 -12
View File
@@ -1,14 +1,88 @@
// Simple fetch to populate visit list
const visitList = document.getElementById('visit-list');
async function loadVisits() {
const resp = await fetch('http://localhost:8000/visits/');
const data = await resp.json();
visitList.innerHTML = '';
data.forEach(v => {
const li = document.createElement('li');
li.textContent = `${new Date(v.start_time).toLocaleString()} - ${v.duration_minutes} min`;
visitList.appendChild(li);
// ---------------------------------------------------------------------
// Helper: call the API relative to the current host (no hard‑coded host)
const api = async (method, endpoint, data) => {
const res = await fetch(`/${endpoint}`, {
method,
headers: { 'Content-Type': 'application/json' },
body: data ? JSON.stringify(data) : null,
});
if (!res.ok) throw await res.json();
return res.json();
};
// ---------------------------------------------------------------------
// Load Providers
const providersList = document.getElementById('providers-list');
const providerForm = document.getElementById('provider-form');
const providerSelect = document.querySelector('#service-form select[name="provider_id"]');
const visitProviderSelect = document.querySelector('#visit-form select[name="provider_id"]');
async function loadProviders() {
const providers = await api('GET', 'providers/');
providersList.innerHTML = `<ul>${providers.map(p => `<li>${p.name} (${p.hourly_rate || 'n/a'})</li>`).join('')}</ul>`;
const opts = providers.map(p => `<option value="${p.id}">${p.name}</option>`).join('');
providerSelect.innerHTML = opts;
visitProviderSelect.innerHTML = opts;
}
loadVisits();
// Could add intervals or form handling later
providerForm.addEventListener('submit', async e => {
e.preventDefault();
const data = Object.fromEntries(new FormData(e.target).entries());
if (!data.hourly_rate) delete data.hourly_rate;
await api('POST', 'providers/', data);
await loadProviders();
});
// ---------------------------------------------------------------------
// Load Clients
const clientsList = document.getElementById('clients-list');
const clientForm = document.getElementById('client-form');
const clientSelect = document.querySelector('#visit-form select[name="client_id"]');
async function loadClients() {
const clients = await api('GET', 'clients/');
clientsList.innerHTML = `<ul>${clients.map(c => `<li>${c.name}</li>`).join('')}</ul>`;
clientSelect.innerHTML = clients.map(c => `<option value="${c.id}">${c.name}</option>`).join('');
}
clientForm.addEventListener('submit', async e => {
e.preventDefault();
const data = Object.fromEntries(new FormData(e.target).entries());
await api('POST', 'clients/', data);
await loadClients();
});
// ---------------------------------------------------------------------
// Load Services
const servicesList = document.getElementById('services-list');
const serviceForm = document.getElementById('service-form');
async function loadServices() {
const services = await api('GET', 'services/');
servicesList.innerHTML = `<ul>${services.map(s => `<li>${s.name} @ $${s.price} (${s.duration_minutes || 'n/a'}min)</li>`).join('')}</ul>`;
}
serviceForm.addEventListener('submit', async e => {
e.preventDefault();
const data = Object.fromEntries(new FormData(e.target).entries());
if (!data.duration_minutes) delete data.duration_minutes;
await api('POST', 'services/', data);
await loadServices();
});
// ---------------------------------------------------------------------
// Load Visits
const visitsList = document.getElementById('visits-list');
const visitForm = document.getElementById('visit-form');
async function loadVisits() {
const visits = await api('GET', 'visits/');
visitsList.innerHTML = `<ul>${visits.map(v => `<li>${new Date(v.start_time).toLocaleString()} – ${v.duration_minutes}min (Provider #${v.provider_id} • Client #${v.client_id})</li>`).join('')}</ul>`;
}
visitForm.addEventListener('submit', async e => {
e.preventDefault();
const data = Object.fromEntries(new FormData(e.target).entries());
if (data.start_time) data.start_time = new Date(data.start_time).toISOString();
await api('POST', 'visits/', data);
await loadVisits();
});
// ---------------------------------------------------------------------
// Initial load
async function init() {
await Promise.all([loadProviders(), loadClients(), loadServices(), loadVisits()]);
}
init();
+55 -20
View File
@@ -1,20 +1,55 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Fitness Tracker Dashboard</title>
<style>
body {font-family: Arial, sans-serif; margin: 20px;}
.card {border: 1px solid #ddd; padding: 10px; margin-bottom: 10px;}
h2 {margin-top: 0;}
</style>
</head>
<body>
<h1>Fitness Tracker Dashboard</h1>
<div id="visits" class="card">
<h2>Visits</h2>
<ul id="visit-list"></ul>
</div>
<script src="app.js"></script>
</body>
</html>
@@
- <h1>Fitness Tracker Dashboard</h1>
- <div id="visits" class="card">
- <h2>Visits</h2>
- <ul id="visit-list"></ul>
- </div>
- <script src="app.js"></script>
+ <h1>Fitness Tracker Dashboard</h1>
+
+ <div class="card">
+ <h2>Providers</h2>
+ <form id="provider-form">
+ <div><label>Name: <input name="name" required></label></div>
+ <div><label>Photo URL: <input name="photo_url"></label></div>
+ <div><label>Hourly Rate: <input name="hourly_rate" type="number" step="0.01"></label></div>
+ <button type="submit">Add Provider</button>
+ </form>
+ <div class="list" id="providers-list"></div>
+ </div>
+
+ <div class="card">
+ <h2>Clients</h2>
+ <form id="client-form">
+ <div><label>Name: <input name="name" required></label></div>
+ <button type="submit">Add Client</button>
+ </form>
+ <div class="list" id="clients-list"></div>
+ </div>
+
+ <div class="card">
+ <h2>Services</h2>
+ <form id="service-form">
+ <div><label>Provider: <select name="provider_id" required></select></label></div>
+ <div><label>Name: <input name="name" required></label></div>
+ <div><label>Price: <input name="price" type="number" step="0.01" required></label></div>
+ <div><label>Duration (min): <input name="duration_minutes" type="number"></label></div>
+ <button type="submit">Add Service</button>
+ </form>
+ <div class="list" id="services-list"></div>
+ </div>
+
+ <div class="card">
+ <h2>Visits</h2>
+ <form id="visit-form">
+ <div><label>Provider: <select name="provider_id" required></select></label></div>
+ <div><label>Client: <select name="client_id" required></select></label></div>
+ <div><label>Start Time: <input name="start_time" type="datetime-local"></label></div>
+ <div><label>Duration (min): <input name="duration_minutes" type="number" required></label></div>
+ <button type="submit">Add Visit</button>
+ </form>
+ <div class="list" id="visits-list"></div>
+ </div>
+
+ <script src="app.js"></script>
*** End Patch