Favoritenseite Dynamisch gemacht

This commit is contained in:
2026-04-10 20:15:57 +02:00
parent 82c7b73f77
commit ddbda72c68
3 changed files with 353 additions and 51 deletions
+17
View File
@@ -82,6 +82,23 @@ CREATE TABLE IF NOT EXISTS `app_user_locations` (
-- Daten-Export vom Benutzer nicht ausgewählt
-- Exportiere Struktur von Tabelle d0467f49.app_user_comets
CREATE TABLE IF NOT EXISTS `app_user_comets` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) unsigned NOT NULL,
`comet_id` bigint(20) unsigned NOT NULL,
`is_favorite` tinyint(1) NOT NULL DEFAULT 0,
`created_at` datetime NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`),
UNIQUE KEY `uq_app_user_comets_user_comet` (`user_id`,`comet_id`),
KEY `idx_app_user_comets_user_id` (`user_id`),
KEY `idx_app_user_comets_comet_id` (`comet_id`),
CONSTRAINT `fk_app_user_comets_comet_id` FOREIGN KEY (`comet_id`) REFERENCES `comets_mpc` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `fk_app_user_comets_user_id` FOREIGN KEY (`user_id`) REFERENCES `app_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- Daten-Export vom Benutzer nicht ausgewählt
-- Exportiere Struktur von Tabelle d0467f49.app_user_minorplanets
CREATE TABLE IF NOT EXISTS `app_user_minorplanets` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+16
View File
@@ -927,6 +927,17 @@ footer a:hover { color: var(--gold); }
border-color: var(--cyan);
}
.btn-secondary.favorite-active {
border-color: var(--gold-dim);
color: var(--gold);
}
.btn-secondary.favorite-active:hover {
background: rgba(201, 168, 76, 0.12);
border-color: var(--gold);
color: var(--gold-pale);
}
.btn-danger {
border-color: rgba(200, 60, 60, 0.35);
color: #f08080;
@@ -1368,6 +1379,11 @@ footer a:hover { color: var(--gold); }
margin: 0;
}
.favorite-text {
color: var(--gold);
font-weight: 600;
}
@media (max-width: 720px) {
.favorites-search-summary {
flex-direction: column;
+320 -51
View File
@@ -34,8 +34,10 @@ $errors = [];
$successMessage = '';
$satelliteSearchResults = [];
$minorplanetSearchResults = [];
$cometSearchResults = [];
$satelliteSearchQuery = trim($_GET['sat_q'] ?? '');
$minorplanetSearchQuery = trim($_GET['mp_q'] ?? '');
$cometSearchQuery = trim($_GET['com_q'] ?? '');
$pageTitle = 'Favoriten - AstroTools';
$headerIntroPre = 'Merkliste';
$headerIntroTitle = 'Favoriten';
@@ -98,12 +100,12 @@ function renderLocationsSection(array $locations, bool $oob = false): string
<tbody>
<?php foreach ($locations as $location): ?>
<tr>
<td><?= h($location['name']) ?></td>
<td><?= h((string) $location['latitude']) ?></td>
<td><?= h((string) $location['longitude']) ?></td>
<td><?= h($location['elevation'] !== null ? (string) $location['elevation'] . ' m' : '-') ?></td>
<td><?= h($location['timezone']) ?></td>
<td><?= (int) $location['is_default'] === 1 ? '*' : '-' ?></td>
<td class="<?= (int) $location['is_default'] === 1 ? 'favorite-text' : '' ?>"><?= h($location['name']) ?></td>
<td class="<?= (int) $location['is_default'] === 1 ? 'favorite-text' : '' ?>"><?= h((string) $location['latitude']) ?></td>
<td class="<?= (int) $location['is_default'] === 1 ? 'favorite-text' : '' ?>"><?= h((string) $location['longitude']) ?></td>
<td class="<?= (int) $location['is_default'] === 1 ? 'favorite-text' : '' ?>"><?= h($location['elevation'] !== null ? (string) $location['elevation'] . ' m' : '-') ?></td>
<td class="<?= (int) $location['is_default'] === 1 ? 'favorite-text' : '' ?>"><?= h($location['timezone']) ?></td>
<td class="<?= (int) $location['is_default'] === 1 ? 'favorite-text' : '' ?>"><?= (int) $location['is_default'] === 1 ? '*' : '-' ?></td>
<td class="action-cell">
<button
type="button"
@@ -188,9 +190,7 @@ function renderSatelliteSearchResults(string $satelliteSearchQuery, array $satel
<td><?= h($satellite['object_name']) ?></td>
<td><?= h((string) $satellite['norad_cat_id']) ?></td>
<td>
<?php if ((int) $satellite['already_added'] === 1): ?>
<span class="hint">Bereits hinzugefuegt</span>
<?php else: ?>
<?php if ((int) $satellite['already_added'] !== 1): ?>
<form method="post" action="" class="favorites-loading-form favorites-loading-form-htmx" data-loading-message="Satellit wird hinzugefuegt..." hx-post="my_favorites.php" hx-target="#favorites-messages" hx-swap="outerHTML">
<input type="hidden" name="action" value="add_satellite">
<input type="hidden" name="satellite_id" value="<?= (int) $satellite['id'] ?>">
@@ -255,9 +255,7 @@ function renderMinorplanetSearchResults(string $minorplanetSearchQuery, array $m
<td><?= h($minorplanet['designation_text'] ?: $minorplanet['desig_packed']) ?></td>
<td><?= h($minorplanet['mp_number'] !== null ? (string) $minorplanet['mp_number'] : '-') ?></td>
<td>
<?php if ((int) $minorplanet['already_added'] === 1): ?>
<span class="hint">Bereits hinzugefuegt</span>
<?php else: ?>
<?php if ((int) $minorplanet['already_added'] !== 1): ?>
<form method="post" action="" class="favorites-loading-form favorites-loading-form-htmx" data-loading-message="Kleinplanet wird hinzugefuegt..." hx-post="my_favorites.php" hx-target="#favorites-messages" hx-swap="outerHTML">
<input type="hidden" name="action" value="add_minorplanet">
<input type="hidden" name="minorplanet_id" value="<?= (int) $minorplanet['id'] ?>">
@@ -293,17 +291,15 @@ function renderTrackedSatellitesSection(array $trackedSatellites, bool $oob = fa
<th>Name</th>
<th>NORAD</th>
<th>Favorit</th>
<th>Hinzugefuegt</th>
<th></th>
</tr>
</thead>
<tbody>
<?php foreach ($trackedSatellites as $satellite): ?>
<tr>
<td><?= h($satellite['object_name']) ?></td>
<td><?= h((string) $satellite['norad_cat_id']) ?></td>
<td><?= (int) $satellite['is_favorite'] === 1 ? '*' : '-' ?></td>
<td><?= h($satellite['created_at']) ?></td>
<td class="<?= (int) $satellite['is_favorite'] === 1 ? 'favorite-text' : '' ?>"><?= h($satellite['object_name']) ?></td>
<td class="<?= (int) $satellite['is_favorite'] === 1 ? 'favorite-text' : '' ?>"><?= h((string) $satellite['norad_cat_id']) ?></td>
<td class="<?= (int) $satellite['is_favorite'] === 1 ? 'favorite-text' : '' ?>"><?= (int) $satellite['is_favorite'] === 1 ? '*' : '-' ?></td>
<td class="action-cell">
<?php if (count($trackedSatellites) <= 1 && (int) $satellite['is_favorite'] === 1): ?>
<span class="hint">Favorit bleibt gesetzt</span>
@@ -311,7 +307,7 @@ function renderTrackedSatellitesSection(array $trackedSatellites, bool $oob = fa
<form method="post" action="" class="favorites-loading-form favorites-loading-form-htmx" data-loading-message="Satelliten-Favorit wird aktualisiert..." hx-post="my_favorites.php" hx-target="#favorites-messages" hx-swap="outerHTML">
<input type="hidden" name="action" value="toggle_satellite_favorite">
<input type="hidden" name="satellite_id" value="<?= (int) $satellite['id'] ?>">
<button type="submit" class="btn btn-sm btn-secondary">
<button type="submit" class="btn btn-sm btn-secondary<?= (int) $satellite['is_favorite'] === 1 ? ' favorite-active' : '' ?>">
<?= (int) $satellite['is_favorite'] === 1 ? 'Favorit entfernen' : 'Als Favorit' ?>
</button>
</form>
@@ -352,22 +348,20 @@ function renderTrackedMinorplanetsSection(array $trackedMinorplanets, bool $oob
<th>Bezeichnung</th>
<th>Nummer</th>
<th>Favorit</th>
<th>Hinzugefuegt</th>
<th></th>
</tr>
</thead>
<tbody>
<?php foreach ($trackedMinorplanets as $minorplanet): ?>
<tr>
<td><?= h($minorplanet['designation_text'] ?: $minorplanet['desig_packed']) ?></td>
<td><?= h($minorplanet['mp_number'] !== null ? (string) $minorplanet['mp_number'] : '-') ?></td>
<td><?= (int) $minorplanet['is_favorite'] === 1 ? '*' : '-' ?></td>
<td><?= h($minorplanet['created_at']) ?></td>
<td class="<?= (int) $minorplanet['is_favorite'] === 1 ? 'favorite-text' : '' ?>"><?= h($minorplanet['designation_text'] ?: $minorplanet['desig_packed']) ?></td>
<td class="<?= (int) $minorplanet['is_favorite'] === 1 ? 'favorite-text' : '' ?>"><?= h($minorplanet['mp_number'] !== null ? (string) $minorplanet['mp_number'] : '-') ?></td>
<td class="<?= (int) $minorplanet['is_favorite'] === 1 ? 'favorite-text' : '' ?>"><?= (int) $minorplanet['is_favorite'] === 1 ? '*' : '-' ?></td>
<td class="action-cell">
<form method="post" action="" class="favorites-loading-form favorites-loading-form-htmx" data-loading-message="Kleinplaneten-Favorit wird aktualisiert..." hx-post="my_favorites.php" hx-target="#favorites-messages" hx-swap="outerHTML">
<input type="hidden" name="action" value="toggle_minorplanet_favorite">
<input type="hidden" name="minorplanet_id" value="<?= (int) $minorplanet['id'] ?>">
<button type="submit" class="btn btn-sm btn-secondary">
<button type="submit" class="btn btn-sm btn-secondary<?= (int) $minorplanet['is_favorite'] === 1 ? ' favorite-active' : '' ?>">
<?= (int) $minorplanet['is_favorite'] === 1 ? 'Favorit entfernen' : 'Als Favorit' ?>
</button>
</form>
@@ -388,6 +382,118 @@ function renderTrackedMinorplanetsSection(array $trackedMinorplanets, bool $oob
return (string) ob_get_clean();
}
function renderCometSearchResults(string $cometSearchQuery, array $cometSearchResults, bool $oob = false): string
{
ob_start();
?>
<div
id="comet-search-results"
class="favorites-search-results<?= $cometSearchQuery !== '' ? ' has-results' : '' ?>"
aria-live="polite"
<?= $oob ? ' hx-swap-oob="outerHTML"' : '' ?>
>
<?php if ($cometSearchQuery === ''): ?>
<div class="favorites-search-empty">
<p>Noch keine Suche gestartet.</p>
<p class="hint">Suche nach MPC-Bezeichnung oder Kometenname, um passende Kometen direkt hier einzublenden.</p>
</div>
<?php else: ?>
<div class="favorites-search-summary">
<h2>Suchergebnisse</h2>
<p class="hint">
<?= count($cometSearchResults) ?> Treffer fuer <strong><?= h($cometSearchQuery) ?></strong>
</p>
</div>
<?php if (empty($cometSearchResults)): ?>
<div class="favorites-search-empty">
<p>Keine passenden Kometen gefunden.</p>
<p class="hint">Probiere eine Bezeichnung wie <strong>67P</strong> oder einen Namen wie <strong>Halley</strong>.</p>
</div>
<?php else: ?>
<div class="favorites-search-table-wrap">
<table class="data-table">
<thead>
<tr>
<th>Bezeichnung</th>
<th></th>
</tr>
</thead>
<tbody>
<?php foreach ($cometSearchResults as $comet): ?>
<tr>
<td><?= h($comet['designation_and_name']) ?></td>
<td>
<?php if ((int) $comet['already_added'] !== 1): ?>
<form method="post" action="" class="favorites-loading-form favorites-loading-form-htmx" data-loading-message="Komet wird hinzugefuegt..." hx-post="my_favorites.php" hx-target="#favorites-messages" hx-swap="outerHTML">
<input type="hidden" name="action" value="add_comet">
<input type="hidden" name="comet_id" value="<?= (int) $comet['id'] ?>">
<button type="submit" class="btn btn-sm btn-primary">Hinzufuegen</button>
</form>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
<?php endif; ?>
</div>
<?php
return (string) ob_get_clean();
}
function renderTrackedCometsSection(array $trackedComets, bool $oob = false): string
{
ob_start();
?>
<div class="card" id="tracked-comets-section"<?= $oob ? ' hx-swap-oob="outerHTML"' : '' ?>>
<h2>Meine Kometen</h2>
<?php if (empty($trackedComets)): ?>
<p class="hint">Du hast noch keine Kometen ausgewaehlt.</p>
<?php else: ?>
<table class="data-table">
<thead>
<tr>
<th>Bezeichnung</th>
<th>Typ</th>
<th>Favorit</th>
<th></th>
</tr>
</thead>
<tbody>
<?php foreach ($trackedComets as $comet): ?>
<tr>
<td class="<?= (int) $comet['is_favorite'] === 1 ? 'favorite-text' : '' ?>"><?= h($comet['designation_and_name']) ?></td>
<td class="<?= (int) $comet['is_favorite'] === 1 ? 'favorite-text' : '' ?>"><?= h((string) $comet['orbit_type']) ?></td>
<td class="<?= (int) $comet['is_favorite'] === 1 ? 'favorite-text' : '' ?>"><?= (int) $comet['is_favorite'] === 1 ? '*' : '-' ?></td>
<td class="action-cell">
<form method="post" action="" class="favorites-loading-form favorites-loading-form-htmx" data-loading-message="Kometen-Favorit wird aktualisiert..." hx-post="my_favorites.php" hx-target="#favorites-messages" hx-swap="outerHTML">
<input type="hidden" name="action" value="toggle_comet_favorite">
<input type="hidden" name="comet_id" value="<?= (int) $comet['id'] ?>">
<button type="submit" class="btn btn-sm btn-secondary<?= (int) $comet['is_favorite'] === 1 ? ' favorite-active' : '' ?>">
<?= (int) $comet['is_favorite'] === 1 ? 'Favorit entfernen' : 'Als Favorit' ?>
</button>
</form>
<form method="post" action="" class="favorites-loading-form favorites-loading-form-htmx" data-loading-message="Komet wird entfernt..." hx-post="my_favorites.php" hx-target="#favorites-messages" hx-swap="outerHTML" onsubmit="return confirm('Komet wirklich entfernen?');">
<input type="hidden" name="action" value="remove_comet">
<input type="hidden" name="comet_id" value="<?= (int) $comet['id'] ?>">
<button type="submit" class="btn btn-sm btn-danger">Entfernen</button>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
<?php
return (string) ob_get_clean();
}
function validTimezone(string $timezone): bool
{
return in_array($timezone, timezone_identifiers_list(), true);
@@ -405,6 +511,9 @@ if (isHtmxRequest()) {
if ($minorplanetSearchQuery === '' && isset($hxQueryParams['mp_q'])) {
$minorplanetSearchQuery = trim((string) $hxQueryParams['mp_q']);
}
if ($cometSearchQuery === '' && isset($hxQueryParams['com_q'])) {
$cometSearchQuery = trim((string) $hxQueryParams['com_q']);
}
}
}
}
@@ -801,6 +910,92 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
}
}
if ($action === 'add_comet') {
$cometId = (int) ($_POST['comet_id'] ?? 0);
if ($cometId <= 0) {
$errors[] = 'Ungueltiger Komet.';
}
if (empty($errors)) {
$stmtCheck = $pdo->prepare("
SELECT `id`
FROM `comets_mpc`
WHERE `id` = :id
LIMIT 1
");
$stmtCheck->execute([
':id' => $cometId,
]);
if (!$stmtCheck->fetch()) {
$errors[] = 'Der Komet wurde nicht gefunden.';
}
}
if (empty($errors)) {
$stmtInsert = $pdo->prepare("
INSERT INTO `app_user_comets` (
`user_id`,
`comet_id`,
`is_favorite`,
`created_at`
) VALUES (
:user_id,
:comet_id,
0,
NOW()
)
ON DUPLICATE KEY UPDATE
`comet_id` = VALUES(`comet_id`)
");
$stmtInsert->execute([
':user_id' => $userId,
':comet_id' => $cometId,
]);
$successMessage = 'Der Komet wurde hinzugefuegt.';
}
}
if ($action === 'remove_comet') {
$cometId = (int) ($_POST['comet_id'] ?? 0);
if ($cometId <= 0) {
$errors[] = 'Ungueltiger Komet.';
}
if (empty($errors)) {
$stmtDelete = $pdo->prepare("
DELETE FROM `app_user_comets`
WHERE `user_id` = :user_id
AND `comet_id` = :comet_id
");
$stmtDelete->execute([
':user_id' => $userId,
':comet_id' => $cometId,
]);
$successMessage = 'Der Komet wurde entfernt.';
}
}
if ($action === 'toggle_comet_favorite') {
$cometId = (int) ($_POST['comet_id'] ?? 0);
if ($cometId <= 0) {
$errors[] = 'Ungueltiger Komet.';
}
if (empty($errors)) {
if (!setExclusiveFavorite($pdo, 'app_user_comets', 'comet_id', $userId, $cometId)) {
$errors[] = 'Der Komet ist nicht in deiner Liste vorhanden.';
} else {
$successMessage = 'Der Kometen-Favorit wurde aktualisiert.';
}
}
}
if ($action === 'add_location') {
$name = trim($_POST['name'] ?? '');
$latitude = trim($_POST['latitude'] ?? '');
@@ -1271,6 +1466,34 @@ if ($minorplanetSearchQuery !== '') {
$minorplanetSearchResults = $stmtMinorplanetSearch->fetchAll();
}
if ($cometSearchQuery !== '') {
$stmtCometSearch = $pdo->prepare("
SELECT
c.`id`,
c.`designation_and_name`,
c.`designation_packed`,
c.`orbit_type`,
CASE
WHEN auc.`comet_id` IS NULL THEN 0
ELSE 1
END AS `already_added`
FROM `comets_mpc` c
LEFT JOIN `app_user_comets` auc
ON auc.`comet_id` = c.`id`
AND auc.`user_id` = :user_id
WHERE c.`designation_and_name` LIKE :query
OR c.`designation_packed` LIKE :query
ORDER BY c.`orbit_type` ASC, c.`designation_and_name` ASC
LIMIT 50
");
$stmtCometSearch->execute([
':user_id' => $userId,
':query' => '%' . $cometSearchQuery . '%',
]);
$cometSearchResults = $stmtCometSearch->fetchAll();
}
$stmtTrackedSatellites = $pdo->prepare("
SELECT
s.`id`,
@@ -1308,6 +1531,24 @@ $stmtTrackedMinorplanets->execute([
]);
$trackedMinorplanets = $stmtTrackedMinorplanets->fetchAll();
$stmtTrackedComets = $pdo->prepare("
SELECT
c.`id`,
c.`designation_and_name`,
c.`orbit_type`,
auc.`is_favorite`,
auc.`created_at`
FROM `app_user_comets` auc
INNER JOIN `comets_mpc` c
ON c.`id` = auc.`comet_id`
WHERE auc.`user_id` = :user_id
ORDER BY auc.`is_favorite` DESC, c.`orbit_type` ASC, c.`designation_and_name` ASC
");
$stmtTrackedComets->execute([
':user_id' => $userId,
]);
$trackedComets = $stmtTrackedComets->fetchAll();
if (isHtmxRequest()) {
if ($_SERVER['REQUEST_METHOD'] === 'GET' && array_key_exists('sat_q', $_GET)) {
echo renderSatelliteSearchResults($satelliteSearchQuery, $satelliteSearchResults);
@@ -1319,6 +1560,11 @@ if (isHtmxRequest()) {
exit;
}
if ($_SERVER['REQUEST_METHOD'] === 'GET' && array_key_exists('com_q', $_GET)) {
echo renderCometSearchResults($cometSearchQuery, $cometSearchResults);
exit;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if ($htmxTriggers !== []) {
header('HX-Trigger: ' . (string) json_encode($htmxTriggers));
@@ -1328,8 +1574,10 @@ if (isHtmxRequest()) {
echo renderLocationsSection($locations, true);
echo renderSatelliteSearchResults($satelliteSearchQuery, $satelliteSearchResults, true);
echo renderMinorplanetSearchResults($minorplanetSearchQuery, $minorplanetSearchResults, true);
echo renderCometSearchResults($cometSearchQuery, $cometSearchResults, true);
echo renderTrackedSatellitesSection($trackedSatellites, true);
echo renderTrackedMinorplanetsSection($trackedMinorplanets, true);
echo renderTrackedCometsSection($trackedComets, true);
exit;
}
}
@@ -1368,12 +1616,12 @@ $loggedIn = true;
<tbody>
<?php foreach ($locations as $location): ?>
<tr>
<td><?= h($location['name']) ?></td>
<td><?= h((string) $location['latitude']) ?></td>
<td><?= h((string) $location['longitude']) ?></td>
<td><?= h($location['elevation'] !== null ? (string) $location['elevation'] . ' m' : '-') ?></td>
<td><?= h($location['timezone']) ?></td>
<td><?= (int) $location['is_default'] === 1 ? '*' : '-' ?></td>
<td class="<?= (int) $location['is_default'] === 1 ? 'favorite-text' : '' ?>"><?= h($location['name']) ?></td>
<td class="<?= (int) $location['is_default'] === 1 ? 'favorite-text' : '' ?>"><?= h((string) $location['latitude']) ?></td>
<td class="<?= (int) $location['is_default'] === 1 ? 'favorite-text' : '' ?>"><?= h((string) $location['longitude']) ?></td>
<td class="<?= (int) $location['is_default'] === 1 ? 'favorite-text' : '' ?>"><?= h($location['elevation'] !== null ? (string) $location['elevation'] . ' m' : '-') ?></td>
<td class="<?= (int) $location['is_default'] === 1 ? 'favorite-text' : '' ?>"><?= h($location['timezone']) ?></td>
<td class="<?= (int) $location['is_default'] === 1 ? 'favorite-text' : '' ?>"><?= (int) $location['is_default'] === 1 ? '*' : '-' ?></td>
<td class="action-cell">
<button
type="button"
@@ -1512,7 +1760,7 @@ $loggedIn = true;
<div class="grid-2">
<div class="card">
<h2>Satelliten suchen</h2>
<form method="get" action="" class="favorites-loading-form favorites-loading-form-htmx favorites-search-form" data-loading-message="Satelliten werden gesucht. Das kann kurz dauern..." hx-get="my_favorites.php" hx-target="#satellite-search-results" hx-swap="outerHTML" hx-push-url="true">
<form method="get" action="" class="favorites-loading-form favorites-loading-form-htmx favorites-search-form" data-loading-message="Satelliten werden gesucht. Das kann kurz dauern..." hx-get="my_favorites.php" hx-target="#satellite-search-results" hx-swap="outerHTML" hx-push-url="false">
<div class="input-row">
<input
type="text"
@@ -1547,9 +1795,7 @@ $loggedIn = true;
<td><?= h($satellite['object_name']) ?></td>
<td><?= h((string) $satellite['norad_cat_id']) ?></td>
<td>
<?php if ((int) $satellite['already_added'] === 1): ?>
<span class="hint">Bereits hinzugefuegt</span>
<?php else: ?>
<?php if ((int) $satellite['already_added'] !== 1): ?>
<form method="post" action="" class="favorites-loading-form favorites-loading-form-htmx" data-loading-message="Satellit wird hinzugefuegt..." hx-post="my_favorites.php" hx-target="#favorites-messages" hx-swap="outerHTML">
<input type="hidden" name="action" value="add_satellite">
<input type="hidden" name="satellite_id" value="<?= (int) $satellite['id'] ?>">
@@ -1574,7 +1820,6 @@ $loggedIn = true;
<div class="card">
<h2>Kleinplaneten suchen</h2>
<p class="hint">Die Treffer werden direkt in der Karte aktualisiert, ohne die ganze Seite neu zu laden.</p>
<form
method="get"
action=""
@@ -1583,7 +1828,7 @@ $loggedIn = true;
hx-get="my_favorites.php"
hx-target="#minorplanet-search-results"
hx-swap="outerHTML"
hx-push-url="true"
hx-push-url="false"
>
<div class="input-row">
<input
@@ -1619,9 +1864,7 @@ $loggedIn = true;
<td><?= h($minorplanet['designation_text'] ?: $minorplanet['desig_packed']) ?></td>
<td><?= h($minorplanet['mp_number'] !== null ? (string) $minorplanet['mp_number'] : '—') ?></td>
<td>
<?php if ((int) $minorplanet['already_added'] === 1): ?>
<span class="hint">Bereits hinzugefuegt</span>
<?php else: ?>
<?php if ((int) $minorplanet['already_added'] !== 1): ?>
<form method="post" action="" class="favorites-loading-form favorites-loading-form-htmx" data-loading-message="Kleinplanet wird hinzugefuegt..." hx-post="my_favorites.php" hx-target="#favorites-messages" hx-swap="outerHTML">
<input type="hidden" name="action" value="add_minorplanet">
<input type="hidden" name="minorplanet_id" value="<?= (int) $minorplanet['id'] ?>">
@@ -1643,6 +1886,34 @@ $loggedIn = true;
<?php endif; ?>
</div>
</div>
<div class="card">
<h2>Kometen suchen</h2>
<form
method="get"
action=""
class="favorites-loading-form favorites-loading-form-htmx favorites-search-form"
data-loading-message="Kometen werden gesucht. Das kann etwas dauern..."
hx-get="my_favorites.php"
hx-target="#comet-search-results"
hx-swap="outerHTML"
hx-push-url="false"
>
<div class="input-row">
<input
type="text"
id="com_q"
name="com_q"
value="<?= h($cometSearchQuery) ?>"
placeholder="Bezeichnung oder Name, z. B. 67P oder Halley"
>
<button type="submit" class="btn btn-primary">Suchen</button>
</div>
<p class="favorites-loading-hint" data-loading-hint hidden>Kometen werden gesucht. Das kann etwas dauern...</p>
</form>
<?= renderCometSearchResults($cometSearchQuery, $cometSearchResults) ?>
</div>
</div>
<div class="grid-2">
@@ -1657,17 +1928,15 @@ $loggedIn = true;
<th>Name</th>
<th>NORAD</th>
<th>Favorit</th>
<th>Hinzugefuegt</th>
<th></th>
</tr>
</thead>
<tbody>
<?php foreach ($trackedSatellites as $satellite): ?>
<tr>
<td><?= h($satellite['object_name']) ?></td>
<td><?= h((string) $satellite['norad_cat_id']) ?></td>
<td><?= (int) $satellite['is_favorite'] === 1 ? '*' : '-' ?></td>
<td><?= h($satellite['created_at']) ?></td>
<td class="<?= (int) $satellite['is_favorite'] === 1 ? 'favorite-text' : '' ?>"><?= h($satellite['object_name']) ?></td>
<td class="<?= (int) $satellite['is_favorite'] === 1 ? 'favorite-text' : '' ?>"><?= h((string) $satellite['norad_cat_id']) ?></td>
<td class="<?= (int) $satellite['is_favorite'] === 1 ? 'favorite-text' : '' ?>"><?= (int) $satellite['is_favorite'] === 1 ? '*' : '-' ?></td>
<td class="action-cell">
<?php if (count($trackedSatellites) <= 1 && (int) $satellite['is_favorite'] === 1): ?>
<span class="hint">Favorit bleibt gesetzt</span>
@@ -1675,7 +1944,7 @@ $loggedIn = true;
<form method="post" action="" class="favorites-loading-form favorites-loading-form-htmx" data-loading-message="Satelliten-Favorit wird aktualisiert..." hx-post="my_favorites.php" hx-target="#favorites-messages" hx-swap="outerHTML">
<input type="hidden" name="action" value="toggle_satellite_favorite">
<input type="hidden" name="satellite_id" value="<?= (int) $satellite['id'] ?>">
<button type="submit" class="btn btn-sm btn-secondary">
<button type="submit" class="btn btn-sm btn-secondary<?= (int) $satellite['is_favorite'] === 1 ? ' favorite-active' : '' ?>">
<?= (int) $satellite['is_favorite'] === 1 ? 'Favorit entfernen' : 'Als Favorit' ?>
</button>
</form>
@@ -1708,22 +1977,20 @@ $loggedIn = true;
<th>Bezeichnung</th>
<th>Nummer</th>
<th>Favorit</th>
<th>Hinzugefuegt</th>
<th></th>
</tr>
</thead>
<tbody>
<?php foreach ($trackedMinorplanets as $minorplanet): ?>
<tr>
<td><?= h($minorplanet['designation_text'] ?: $minorplanet['desig_packed']) ?></td>
<td><?= h($minorplanet['mp_number'] !== null ? (string) $minorplanet['mp_number'] : '-') ?></td>
<td><?= (int) $minorplanet['is_favorite'] === 1 ? '*' : '-' ?></td>
<td><?= h($minorplanet['created_at']) ?></td>
<td class="<?= (int) $minorplanet['is_favorite'] === 1 ? 'favorite-text' : '' ?>"><?= h($minorplanet['designation_text'] ?: $minorplanet['desig_packed']) ?></td>
<td class="<?= (int) $minorplanet['is_favorite'] === 1 ? 'favorite-text' : '' ?>"><?= h($minorplanet['mp_number'] !== null ? (string) $minorplanet['mp_number'] : '-') ?></td>
<td class="<?= (int) $minorplanet['is_favorite'] === 1 ? 'favorite-text' : '' ?>"><?= (int) $minorplanet['is_favorite'] === 1 ? '*' : '-' ?></td>
<td class="action-cell">
<form method="post" action="" class="favorites-loading-form favorites-loading-form-htmx" data-loading-message="Kleinplaneten-Favorit wird aktualisiert..." hx-post="my_favorites.php" hx-target="#favorites-messages" hx-swap="outerHTML">
<input type="hidden" name="action" value="toggle_minorplanet_favorite">
<input type="hidden" name="minorplanet_id" value="<?= (int) $minorplanet['id'] ?>">
<button type="submit" class="btn btn-sm btn-secondary">
<button type="submit" class="btn btn-sm btn-secondary<?= (int) $minorplanet['is_favorite'] === 1 ? ' favorite-active' : '' ?>">
<?= (int) $minorplanet['is_favorite'] === 1 ? 'Favorit entfernen' : 'Als Favorit' ?>
</button>
</form>
@@ -1739,6 +2006,8 @@ $loggedIn = true;
</table>
<?php endif; ?>
</div>
<?= renderTrackedCometsSection($trackedComets) ?>
</div>
<script src="js/htmx.min.js"></script>