lots of front-end work

This commit is contained in:
matt committed 2026-10-16 04:31:50 -07:00
1 parent bd9eb7798f
commit 9b98c652ef
4 files changed
+275 -14

No files matched your search

+39 -13
View File
@@ -28,6 +28,26 @@ function callApi(string $method, string $path, $body = null)
return json_decode($response, true); return json_decode($response, true);
} }
// Fetch rate options setting
$rateOptionsSetting = callApi('GET', '/settings/rate_options');
$rateOptions = [];
if ($rateOptionsSetting && isset($rateOptionsSetting['value'])) {
$parsed = json_decode($rateOptionsSetting['value'], true);
if (is_array($parsed)) {
$rateOptions = $parsed;
}
}
// Update form handling to process selected rates
$selectedRates = $_POST['rates'] ?? [];
$ratesArray = [];
foreach ($selectedRates as $item) {
$parts = explode(':', $item, 2);
if (count($parts) == 2) {
$ratesArray[] = [$parts[0] => $parts[1]];
}
}
$created = null; $created = null;
$errors = []; $errors = [];
@@ -37,26 +57,26 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$phone = trim($_POST['phone'] ?? ''); $phone = trim($_POST['phone'] ?? '');
$age = trim($_POST['age'] ?? ''); $age = trim($_POST['age'] ?? '');
$photo = trim($_POST['photo'] ?? ''); $photo = trim($_POST['photo'] ?? '');
$rates = trim($_POST['rates'] ?? '');
$private = isset($_POST['private']) ? true : false; $private = isset($_POST['private']) ? true : false;
// Basic validation // Basic validation
if ($name === '') { $errors[] = 'Name is required.'; } if ($name === '') { $errors[] = 'Name is required.'; }
if ($age !== '' && !is_numeric($age)) { $errors[] = 'Age must be a number.'; } if ($age !== '' && !is_numeric($age)) { $errors[] = 'Age must be a number.'; }
if ($rates !== '' && !is_numeric($rates)) { $errors[] = 'Rates must be a number.'; } // Rates now processed from checkboxes
if (empty($errors)) { if (empty($errors)) {
$body = [ $body = [
'name' => $name, 'name' => $name,
'phone' => $phone, 'phone' => $phone,
'age' => $age === '' ? null : (int)$age, 'age' => $age === '' ? null : (int)$age,
'photo' => $photo === '' ? null : $photo, 'photo' => $photo === '' ? null : $photo,
'rates' => $rates === '' ? null : (float)$rates, 'rates' => empty($ratesArray) ? null : $ratesArray,
'private'=> $private 'private'=> $private
]; ];
$result = callApi('POST', '/providers', $body); $result = callApi('POST', '/providers', $body);
if ($result) { if ($result) {
$created = $result; // API returns created provider object // On successful creation, redirect to the list providers page
header('Location: list_providers.php');
exit;
} else { } else {
$errors[] = 'Failed to create provider. API error.'; $errors[] = 'Failed to create provider. API error.';
} }
@@ -88,20 +108,26 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
<?php endforeach; ?> <?php endforeach; ?>
</div> </div>
<?php endif; ?> <?php endif; ?>
<?php if ($created): ?>
<div class="success">
<p>Provider created successfully with ID <?=htmlspecialchars($created['id'] ?? '')?>.</p>
</div>
<?php endif; ?>
<form method="post" action=""> <form method="post" action="">
<label>Name:<br><input type="text" name="name" value="<?=htmlspecialchars($_POST['name'] ?? '')?>" required></label> <label>Name:<br><input type="text" name="name" value="<?=htmlspecialchars($_POST['name'] ?? '')?>" required></label>
<label>Phone:<br><input type="text" name="phone" value="<?=htmlspecialchars($_POST['phone'] ?? '')?>"></label> <label>Phone:<br><input type="text" name="phone" value="<?=htmlspecialchars($_POST['phone'] ?? '')?>"></label>
<label>Age:<br><input type="number" name="age" value="<?=htmlspecialchars($_POST['age'] ?? '')?>"></label> <label>Age:<br><input type="number" name="age" value="<?=htmlspecialchars($_POST['age'] ?? '')?>"></label>
<label>Photo URL:<br><input type="text" name="photo" value="<?=htmlspecialchars($_POST['photo'] ?? '')?>"></label> <label>Photo URL:<br><input type="text" name="photo" value="<?=htmlspecialchars($_POST['photo'] ?? '')?>"></label>
<label>Rates:<br><input type="text" name="rates" value="<?=htmlspecialchars($_POST['rates'] ?? '')?>"></label> <?php if (!empty($rateOptions)) : ?>
<label><input type="checkbox" name="private" <?=isset($_POST['private'])?'checked':''?>> Private</label> <label>Rate Options:<br>
<button type="submit">Create Provider</button> <?php foreach ($rateOptions as $option) :
$key = key($option);
$value = $option[$key];
?>
<input type="checkbox" name="rates[]" value="<?=htmlspecialchars($key . ':' . $value)?>" <?php if (in_array($key . ':' . $value, $selectedRates)) echo 'checked'; ?>> <?=htmlspecialchars($key)?>: <?=htmlspecialchars($value)?>
<?php endforeach; ?>
</label>
<?php endif; ?>
<label><input type="checkbox" name="private" <?=isset($_POST['private'])?'checked':''?>> Private</label><br>
<button type="submit" class="btn">Create Provider</button>
</form> </form>
</div> </div>
</body> </body>
</html> </html>
+100
View File
@@ -0,0 +1,100 @@
<?php
// Correct array syntax and fix PHP errors in edit_provider.php
// edit_provider.php
// This page allows editing a provider's details.
// It expects a provider id passed via the query string: ?id=123
$provider_id = isset($_GET['id']) ? intval($_GET['id']) : 0;
if ($provider_id <= 0) {
echo '<h1>Error</h1>' .
'<p>Provider ID is missing or invalid.</p>';
exit;
}
// API base URL
$api_base = 'http://172.25.1.105:5000';
// Handle form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Collect submitted data
$payload = [
'name' => $_POST['name'] ?? '',
'age' => (int)($_POST['age'] ?? 0),
'photo' => $_POST['photo'] ?? '',
'phone' => $_POST['phone'] ?? '',
'rates' => json_decode($_POST['rates'] ?? 'null', true) ?? [],
'private' => isset($_POST['private']) && $_POST['private'] === 'on',
];
// Send PUT request to API
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api_base . '/providers/' . $provider_id);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode >= 400) {
$error = json_decode($response, true)['error'] ?? 'Update failed';
echo '<h1>Error</h1><p>' . htmlspecialchars($error) . '</p>';
} else {
// Success: redirect back to provider list
header('Location: list_providers.php');
exit;
}
}
// Fetch current provider details for the form (GET request)
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api_base . '/providers?id=' . $provider_id);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode >= 400) {
echo '<h1>Error</h1><p>Could not load provider details.</p>';
exit;
}
$provider = json_decode($response, true);
// API may return array for GET by id
if (is_array($provider) && count($provider) > 0 && isset($provider[0])) {
$provider = $provider[0];
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Edit Provider</title>
<link rel="stylesheet" href="https://cosmostat.matt-cloud.com/src/styles.css">
<style>
body {font-family: Arial, sans-serif; margin: 20px;}
form {max-width: 600px;}
label {display: block; margin-top: 10px;}
input[type=text], input[type=number], textarea {width: 100%; padding: 8px; box-sizing: border-box;}
input[type=checkbox] {margin-top: 5px;}
button {margin-top: 15px; padding: 10px 15px;}
</style>
</head>
<body>
<div class="card">
<h1>Edit Provider</h1>
<form method="post" id="editForm">
<label>Name: <input type="text" name="name" id="name" required value="<?php echo htmlspecialchars($provider['name'] ?? ''); ?>"></label>
<label>Age: <input type="number" name="age" id="age" required value="<?php echo htmlspecialchars($provider['age'] ?? ''); ?>"></label>
<label>Photo URL: <input type="text" name="photo" id="photo" value="<?php echo htmlspecialchars($provider['photo'] ?? ''); ?>"></label>
<label>Phone: <input type="text" name="phone" id="phone" required value="<?php echo htmlspecialchars($provider['phone'] ?? ''); ?>"></label>
<label>Rates (JSON):<textarea name="rates" id="rates" rows="4"><?php echo htmlspecialchars(json_encode($provider['rates'] ?? [], JSON_PRETTY_PRINT)); ?></textarea></label>
<label>Private: <input type="checkbox" name="private" id="private" <?php echo (!empty($provider['private'])) ? 'checked' : ''; ?>></label>
<button type="submit">Save</button>
<button type="button" onclick="window.location.href='list_providers.php'">Cancel</button>
</form>
</div>
</body>
</html>
+9 -1
View File
@@ -39,18 +39,21 @@ $providers = $providers ?? [];
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Providers</title> <title>Providers</title>
<link rel="stylesheet" href="https://cosmostat.matt-cloud.com/src/styles.css"> <link rel="stylesheet" href="https://cosmostat.matt-cloud.com/src/styles.css">
<style> <style>
body { font-family: Arial, sans-serif; margin: 2rem; } body { font-family: Arial, sans-serif; margin: 2rem; }
#search { margin-bottom: 1rem; padding: 0.5rem; width: 300px; } #search { margin-bottom: 1rem; padding: 0.5rem; width: 300px; }
table { width: 100%; border-collapse: collapse; } table { width: 100%; border-collapse: collapse; }
img { max-width: 60px; height: auto; } img { max-width: 60px; height: auto; }
.header-container { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; }
</style> </style>
</head> </head>
<body> <body>
<div class="card"> <div class="card">
<div class="header-container">
<h1>Providers</h1> <h1>Providers</h1>
<a href="add_provider.php" class="btn">Add Provider</a>
</div>
<input type="text" id="search" placeholder="Search providers..."> <input type="text" id="search" placeholder="Search providers...">
<table id="providers-table"> <table id="providers-table">
<thead> <thead>
@@ -62,6 +65,7 @@ $providers = $providers ?? [];
<th data-field="photo">Photo</th> <th data-field="photo">Photo</th>
<th data-field="rates">Rates</th> <th data-field="rates">Rates</th>
<th data-field="private">Private</th> <th data-field="private">Private</th>
<th>Actions</th>
</tr> </tr>
</thead> </thead>
<tbody></tbody> <tbody></tbody>
@@ -84,6 +88,7 @@ function renderTable(data) {
<td>${p.photo ? `<img src="${p.photo}" alt="Photo">` : ''}</td> <td>${p.photo ? `<img src="${p.photo}" alt="Photo">` : ''}</td>
<td>${p.rates}</td> <td>${p.rates}</td>
<td>${p.private ? 'Yes' : 'No'}</td> <td>${p.private ? 'Yes' : 'No'}</td>
<td><a href="edit_provider.php?id=${p.id}">Edit</a></td>
`; `;
tbody.appendChild(tr); tbody.appendChild(tr);
}); });
@@ -118,6 +123,7 @@ renderTable(providers);
document.querySelectorAll('#providers-table th').forEach(th => { document.querySelectorAll('#providers-table th').forEach(th => {
th.addEventListener('click', () => { th.addEventListener('click', () => {
const field = th.getAttribute('data-field'); const field = th.getAttribute('data-field');
if (!field) return;
sortData(field); sortData(field);
}); });
}); });
@@ -135,3 +141,5 @@ document.getElementById('search').addEventListener('input', e => {
</script> </script>
</body> </body>
</html> </html>
+127
View File
@@ -0,0 +1,127 @@
<?php
// settings.php
// This page displays all settings stored in the Flask API and allows editing them.
// It supports updating existing settings via PUT and creating a single new setting via POST.
// The design follows the pattern used in list_providers.php.
// --- Helper to call the Flask API -------------------------------------------
function callApi(string $method, string $path, $body = null)
{
// API base URL – update if your API is hosted elsewhere
$url = 'http://172.25.1.105:5000' . $path;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
if ($body !== null) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
}
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode >= 400) {
return null; // Could also throw an exception if preferred
}
return json_decode($response, true);
}
$messages = [];
// Handle form submission – update existing settings and/or create a new one
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Update existing settings
if (isset($_POST['orig_name'], $_POST['value'])) {
foreach ($_POST['orig_name'] as $idx => $orig) {
$newVal = $_POST['value'][$idx] ?? '';
if ($newVal === '') continue; // skip empty values
$res = callApi('PUT', '/settings/' . urlencode($orig), ['value' => $newVal]);
if ($res === null) {
$messages[] = "Failed to update setting '" . htmlspecialchars($orig) . "'.";
} else {
$messages[] = "Updated setting '" . htmlspecialchars($orig) . "'.";
}
}
}
// Create a single new setting
$newName = $_POST['new_name'] ?? '';
$newValue = $_POST['new_value'] ?? '';
if ($newName !== '' && $newValue !== '') {
$res = callApi('POST', '/settings', ['name' => $newName, 'value' => $newValue]);
if ($res === null) {
$messages[] = "Failed to create new setting '" . htmlspecialchars($newName) . "'.";
} else {
$messages[] = "Created new setting '" . htmlspecialchars($newName) . "'.";
}
} elseif ($newName !== '' || $newValue !== '') {
$messages[] = "Both name and value are required to create a new setting.";
}
}
// Retrieve current settings to display
$settings = callApi('GET', '/settings');
$settings = $settings ?? [];
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Settings</title>
<link rel="stylesheet" href="https://cosmostat.matt-cloud.com/src/styles.css">
<style>
body {font-family: Arial, sans-serif; margin: 2rem;}
.messages {margin-bottom: 1rem;}
.messages .error {color: red;}
.messages .success {color: green;}
table {width: 100%; border-collapse: collapse;}
input[type=text] {width: 95%;}
.btn {padding: 6px 12px; margin-top: 10px;}
</style>
</head>
<body>
<div class="card">
<h1>Settings</h1>
<?php if (!empty($messages)) : ?>
<div class="messages">
<?php foreach ($messages as $msg) : ?>
<div class="success"><?= htmlspecialchars($msg) ?></div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<form method="post">
<table>
<thead>
<tr>
<th>Name</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<?php if (!empty($settings)) : ?>
<?php foreach ($settings as $s) : ?>
<tr>
<td><?= htmlspecialchars($s['name']) ?></td>
<td>
<input type="text" name="value[]" value="<?= htmlspecialchars($s['value']) ?>" />
<input type="hidden" name="orig_name[]" value="<?= htmlspecialchars($s['name']) ?>" />
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
<tr>
<td><input type="text" name="new_name" placeholder="New setting name" /></td>
<td><input type="text" name="new_value" placeholder="New setting value" /></td>
</tr>
</tbody>
</table>
<input type="submit" value="Save Settings" class="btn" />
</form>
</div>
</body>
</html>