From 269366b7b6e12314ce17e169f62299713c9908bb Mon Sep 17 00:00:00 2001 From: matt Date: Wed, 21 Oct 2026 02:52:36 -0700 Subject: [PATCH] list, add, and edit providers essential functions working --- web/add_provider.php | 23 +++-- web/config.php | 4 +- web/edit_provider.php | 218 ++++++++++++++++++++++++++++++----------- web/list_providers.php | 38 ++++++- 4 files changed, 207 insertions(+), 76 deletions(-) diff --git a/web/add_provider.php b/web/add_provider.php index 84b0b03..8f80890 100644 --- a/web/add_provider.php +++ b/web/add_provider.php @@ -46,15 +46,12 @@ if ($rateOptionsSetting && isset($rateOptionsSetting['value'])) { } // Update form handling to process selected rates -$selectedRates = $_POST['rates'] ?? []; +$selectedRateKeys = $_POST['rate_selected'] ?? []; $ratesArray = []; -foreach ($selectedRates as $item) { - $parts = explode(':', $item, 2); - if (count($parts) == 2) { - $ratesArray[] = [$parts[0] => $parts[1]]; - } +foreach ($selectedRateKeys as $key) { + $value = $_POST['rate_value'][$key] ?? '0'; + $ratesArray[] = [$key => $value]; } - $created = null; $errors = []; @@ -126,14 +123,17 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { @@ -144,4 +144,3 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { - diff --git a/web/config.php b/web/config.php index 37cf5c4..be6a9ee 100644 --- a/web/config.php +++ b/web/config.php @@ -2,7 +2,7 @@ diff --git a/web/edit_provider.php b/web/edit_provider.php index a8e0d78..fe437bd 100644 --- a/web/edit_provider.php +++ b/web/edit_provider.php @@ -1,72 +1,140 @@ - Error' . - '

Provider ID is missing or invalid.

'; + echo '

Error

Provider ID is missing or invalid.

'; exit; } -// API base URL -$url = BASE_API_URL . $path; +// ------------------------------------------------------------------ +// Helper: Call the API (GET/PUT) – returns decoded JSON or null +function callApi(string $method, string $path, $body = null) +{ + $url = BASE_API_URL . $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; + } + return json_decode($response, true); +} +// ------------------------------------------------------------------ -// Handle form submission +// 1️⃣ Get provider details +$provider = callApi('GET', '/providers?id=' . $provider_id); +if (!$provider) { + echo '

Error

Could not load provider details.

'; + exit; +} +if (is_array($provider) && count($provider) > 0 && isset($provider[0])) { + $provider = $provider[0]; +} + +// 2️⃣ Get rate‑option list (comma‑separated string → array) +$rateSetting = callApi('GET', '/settings/rate_options'); +$rateOptions = []; +if ($rateSetting && isset($rateSetting['value'])) { + $rateOptions = array_map('trim', explode(',', $rateSetting['value'])); +} + +// 3️⃣ Decode the API’s rate string (JSON → array of arrays) +$ratesData = $provider['rates'] ?? '[]'; +$decoded = []; +if (is_string($ratesData)) { + $decoded = json_decode($ratesData, true); + if (json_last_error() !== JSON_ERROR_NONE) { + $decoded = []; // bad JSON – treat as empty + } +} elseif (is_array($ratesData)) { + $decoded = $ratesData; // already an array – legacy path +} + +// 4️⃣ Build two helper arrays +$selectedRateKeys = []; // lowercase keys of selected rates +$ratesAssoc = []; // key → value + +foreach ($decoded as $entry) { + if (!is_array($entry)) continue; + foreach ($entry as $k => $v) { + $kTrim = strtolower(trim($k)); + $selectedRateKeys[] = $kTrim; + $ratesAssoc[$kTrim] = $v; + } +} + +// 5️⃣ Find orphan rates (present in $decoded but not in $rateOptions) +$orphanRates = []; +$orphanKeys = []; +foreach ($decoded as $entry) { + if (!is_array($entry)) continue; + foreach ($entry as $k => $v) { + $kTrim = strtolower(trim($k)); + if (!in_array($kTrim, array_map('strtolower', $rateOptions))) { + $orphanRates[$kTrim] = $v; + $orphanKeys[] = $kTrim; + } + } +} + +// ------------------------------------------------------------------ +// 6️⃣ Handle form POST +// --- Handle form POST ------------------------------------------------- if ($_SERVER['REQUEST_METHOD'] === 'POST') { - // Collect submitted data + // Base payload $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', + // Convert checkbox to boolean + 'private' => isset($_POST['private']), ]; - // 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); + // ------------------------------------------------------------------ + // Rebuild the rates array from the form. + $finalRates = []; - if ($httpCode >= 400) { - $error = json_decode($response, true)['error'] ?? 'Update failed'; - echo '

Error

' . htmlspecialchars($error) . '

'; - } else { - // Success: redirect back to provider list + // 1️⃣ Add the selected valid rate options (value may be changed by the user) + $selectedRateKeysRaw = $_POST['rate_selected'] ?? []; + foreach ($selectedRateKeysRaw as $opt) { // $opt is the original rate name + $newVal = $_POST['rate_value'][$opt] ?? '0'; // the updated value + $finalRates[] = [$opt => $newVal]; + } + + // 2️⃣ Add orphan rates that the user chose **not** to delete + $orphanDeleteSet = array_flip(array_map('strtolower', $_POST['orphan_delete'] ?? [])); + foreach ($orphanRates as $key => $value) { // $key is already lower‑cased + if (!isset($orphanDeleteSet[strtolower($key)])) { + $finalRates[] = [$key => $value]; + } + } + + // 3️⃣ Encode the new array as JSON + //$payload['rates'] = !empty($finalRates) ? json_encode($finalRates) : null; + $payload['rates'] = !empty($finalRates) ? $finalRates : null; + + + // ------------------------------------------------------------------ + // Submit the updated provider + $result = callApi('PUT', '/providers/' . $provider_id, $payload); + if ($result) { 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 '

Error

Could not load provider details.

'; - 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]; + echo '

Error

Failed to update provider.

'; } ?> @@ -87,17 +155,49 @@ if (is_array($provider) && count($provider) > 0 && isset($provider[0])) {
-

Edit Provider

-
- - - - - - - - -
+

Edit Provider

+
+ + + + + + + + + + + + + + + + + +
+ + + + +
- + \ No newline at end of file diff --git a/web/list_providers.php b/web/list_providers.php index b9b3dea..57cc7ee 100644 --- a/web/list_providers.php +++ b/web/list_providers.php @@ -34,6 +34,27 @@ function callApi(string $method, string $path, $body = null) $providers = callApi('GET', '/providers'); $providers = $providers ?? []; +// Normalize rates for display +foreach ($providers as &$p) { + $rates = $p['rates'] ?? ''; + if (is_string($rates)) { + $decoded = json_decode($rates, true); + if (json_last_error() !== JSON_ERROR_NONE) { + // try stripping slashes + $unescaped = stripslashes($rates); + $decoded = json_decode($unescaped, true); + } + if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) { + $p['rates'] = $decoded; + } else { + // leave as is + $p['rates'] = $rates; + } + } elseif (is_array($rates)) { + $p['rates'] = $rates; + } +} +unset($p); // ----------------------------------------------------------------------- ?> @@ -77,6 +98,19 @@ $providers = $providers ?? []; const providers = ; let currentSort = { field: null, asc: true }; +// Helper to format rates into readable lines +function formatRates(rates) { + if (!rates) return ''; + if (Array.isArray(rates)) { + return rates.map(r => { + const key = Object.keys(r)[0]; + const val = r[key]; + return `${key}: ${val}`; + }).join('
'); + } + return rates; +} + function renderTable(data) { const tbody = document.querySelector('#providers-table tbody'); tbody.innerHTML = ''; @@ -88,7 +122,7 @@ function renderTable(data) { ${p.phone || ''} ${p.age || ''} ${p.photo ? `Photo` : ''} - ${p.rates} + ${formatRates(p.rates)} ${p.private ? 'Yes' : 'No'} Edit `; @@ -143,5 +177,3 @@ document.getElementById('search').addEventListener('input', e => { - -