lots of front-end work
This commit is contained in:
1 parent
bd9eb7798f
commit
9b98c652ef
4 files changed
+275
-14
No files matched your search
+39
-13
@@ -28,6 +28,26 @@ function callApi(string $method, string $path, $body = null)
|
||||
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;
|
||||
$errors = [];
|
||||
|
||||
@@ -37,26 +57,26 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$phone = trim($_POST['phone'] ?? '');
|
||||
$age = trim($_POST['age'] ?? '');
|
||||
$photo = trim($_POST['photo'] ?? '');
|
||||
$rates = trim($_POST['rates'] ?? '');
|
||||
$private = isset($_POST['private']) ? true : false;
|
||||
|
||||
// Basic validation
|
||||
if ($name === '') { $errors[] = 'Name is required.'; }
|
||||
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)) {
|
||||
$body = [
|
||||
'name' => $name,
|
||||
'phone' => $phone,
|
||||
'age' => $age === '' ? null : (int)$age,
|
||||
'photo' => $photo === '' ? null : $photo,
|
||||
'rates' => $rates === '' ? null : (float)$rates,
|
||||
'rates' => empty($ratesArray) ? null : $ratesArray,
|
||||
'private'=> $private
|
||||
];
|
||||
$result = callApi('POST', '/providers', $body);
|
||||
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 {
|
||||
$errors[] = 'Failed to create provider. API error.';
|
||||
}
|
||||
@@ -88,20 +108,26 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?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="">
|
||||
<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>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>Rates:<br><input type="text" name="rates" value="<?=htmlspecialchars($_POST['rates'] ?? '')?>"></label>
|
||||
<label><input type="checkbox" name="private" <?=isset($_POST['private'])?'checked':''?>> Private</label>
|
||||
<button type="submit">Create Provider</button>
|
||||
<?php if (!empty($rateOptions)) : ?>
|
||||
<label>Rate Options:<br>
|
||||
<?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>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -39,18 +39,21 @@ $providers = $providers ?? [];
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Providers</title>
|
||||
|
||||
<link rel="stylesheet" href="https://cosmostat.matt-cloud.com/src/styles.css">
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; margin: 2rem; }
|
||||
#search { margin-bottom: 1rem; padding: 0.5rem; width: 300px; }
|
||||
table { width: 100%; border-collapse: collapse; }
|
||||
img { max-width: 60px; height: auto; }
|
||||
.header-container { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="card">
|
||||
<div class="header-container">
|
||||
<h1>Providers</h1>
|
||||
<a href="add_provider.php" class="btn">Add Provider</a>
|
||||
</div>
|
||||
<input type="text" id="search" placeholder="Search providers...">
|
||||
<table id="providers-table">
|
||||
<thead>
|
||||
@@ -62,6 +65,7 @@ $providers = $providers ?? [];
|
||||
<th data-field="photo">Photo</th>
|
||||
<th data-field="rates">Rates</th>
|
||||
<th data-field="private">Private</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
@@ -84,6 +88,7 @@ function renderTable(data) {
|
||||
<td>${p.photo ? `<img src="${p.photo}" alt="Photo">` : ''}</td>
|
||||
<td>${p.rates}</td>
|
||||
<td>${p.private ? 'Yes' : 'No'}</td>
|
||||
<td><a href="edit_provider.php?id=${p.id}">Edit</a></td>
|
||||
`;
|
||||
tbody.appendChild(tr);
|
||||
});
|
||||
@@ -118,6 +123,7 @@ renderTable(providers);
|
||||
document.querySelectorAll('#providers-table th').forEach(th => {
|
||||
th.addEventListener('click', () => {
|
||||
const field = th.getAttribute('data-field');
|
||||
if (!field) return;
|
||||
sortData(field);
|
||||
});
|
||||
});
|
||||
@@ -135,3 +141,5 @@ document.getElementById('search').addEventListener('input', e => {
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
Reference in new issue
Block a user