Finish req list, add snoozed list

This commit is contained in:
2024-06-22 22:48:31 -04:00
parent 2369827033
commit d6e8cf66cc
5 changed files with 76 additions and 25 deletions

View File

@@ -2,6 +2,9 @@
namespace MyPrayerJournal;
use BitBadger\PDODocument\Custom;
use BitBadger\PDODocument\Mapper\ExistsMapper;
class Layout
{
/**
@@ -72,7 +75,15 @@ class Layout
* The default navigation bar, which will load the items on page load, and whenever a refresh event occurs
*/
public static function navBar(): void
{ ?>
{
$table = Table::REQUEST;
$hasSnoozed = key_exists('user_id', $_SESSION)
? Custom::scalar(<<<SQL
SELECT EXISTS (
SELECT 1 FROM $table
WHERE data->>'userId' = :userId AND datetime(data->>'snoozedUntil') > datetime('now'))
SQL, [':userId' => $_SESSION['user_id']], new ExistsMapper())
: false; ?>
<nav class="navbar navbar-dark" role="navigation">
<div class=container-fluid><?php
UI::pageLink('/', '<span class=m>my</span><span class=p>Prayer</span><span class=j>Journal</span>',
@@ -81,7 +92,7 @@ class Layout
if (key_exists('user_id', $_SESSION)) {
self::navLink('/journal', 'Journal');
self::navLink('/requests/active', 'Active');
if (key_exists('has_snoozed', $_SESSION)) self::navLink('/requests/snoozed', 'Snoozed');
if ($hasSnoozed) self::navLink('/requests/snoozed', 'Snoozed');
self::navLink('/requests/answered', 'Answered'); ?>
<li class=nav-item><a href=/user/log-off>Log Off</a><?php
} else { ?>

View File

@@ -146,13 +146,15 @@ class Request implements JsonSerializable
* Get either the user's active or answered requests
*
* @param bool $active True to retrieve active requests, false to retrieve answered requests
* @param bool $snoozed True to retrieve only snoozed requests
* @return DocumentList<Request> The requests matching the criteria
* @throws DocumentException If any is encountered
*/
private static function forUser(bool $active = true): DocumentList
private static function forUser(bool $active = true, bool $snoozed = false): DocumentList
{
$table = Table::REQUEST;
$op = $active ? '<>' : '=';
$extra = $snoozed ? "AND datetime(data->>'snoozedUntil') > datetime('now')" : '';
$order = $active
? "coalesce(data->>'snoozedUntil', data->>'showAfter', last_prayed, data->>'$.history[0].asOf')"
: "data->>'$.history[0].asOf' DESC";
@@ -164,7 +166,7 @@ class Request implements JsonSerializable
LIMIT 1) last_prayed
FROM $table r
WHERE data->>'userId' = :userId
AND data->>'$.history[0].action' $op 'Answered'
AND data->>'$.history[0].action' $op 'Answered' $extra
ORDER BY $order
SQL, [':userId' => $_SESSION['user_id']], new DocumentMapper(self::class));
}
@@ -190,4 +192,15 @@ class Request implements JsonSerializable
{
return self::forUser(false);
}
/**
* Get a list of snoozed requests for a user
*
* @return DocumentList<Request> The user's snoozed requests
* @throws DocumentException If any is encountered
*/
public static function snoozed(): DocumentList
{
return self::forUser(snoozed: true);
}
}

View File

@@ -168,19 +168,18 @@ class UI
return $dtFrom > $dtTo ? "$value ago" : "in $value";
}
/**
* Render the given list of requests
*
* @param DocumentList<Request> $reqs The list of requests to render
* @throws Exception If date/time instances are not valid
*/
public static function requestList(DocumentList $reqs): void
{
$btnClass = "btn btn-light mx-2";
$btnClass = "btn btn-light mx-2";
$restoreBtn = fn(string $id, string $link, string $title) =>
'<button class="' . $btnClass. '" hx-patch="/request/' . $link . '?id=' . $id
. '" title="' . htmlspecialchars($title) . '">' . self::icon('restore') . '</button>';
/// Create a request within the list
/* let reqListItem now tz req =
let isFuture instant = defaultArg (instant |> Option.map (fun it -> it > now)) false
let reqId = RequestId.toString req.RequestId
let isPending = (not isSnoozed) && isFuture req.ShowAfter
let restoreBtn (link : string) title =
button [ btnClass; _hxPatch $"/request/{reqId}/{link}"; _title title ] [ icon "restore" ] */ ?>
. '" title="' . htmlspecialchars($title) . '">' . self::icon('restore') . '</button>'; ?>
<div class=list-group><?php
foreach ($reqs->items() as /** @var Request $req */ $req) { ?>
<div class="list-group-item px-0 d-flex flex-row align-items-start" hx-target=this
@@ -197,15 +196,21 @@ class UI
echo $restoreBtn($req->id, 'show', 'Show Now');
}
echo '<p class="request-text mb-0">' . $req->currentText();
// if isSnoozed || isPending || isAnswered then
// br []
// small [ _class "text-muted" ] [
// if isSnoozed then [ str "Snooze expires "; relativeDate req.SnoozedUntil.Value now tz ]
// elif isPending then [ str "Request appears next "; relativeDate req.ShowAfter.Value now tz ]
// else (* isAnswered *) [ str "Answered "; relativeDate req.AsOf now tz ]
// |> em []
// ]
?>
if ($req->isSnoozed() || $req->isPending() || $req->isAnswered()) { ?>
<br>
<small class=text-muted><em><?php
switch (true) {
case $req->isSnoozed():
echo 'Snooze expires '; self::relativeDate($req->snoozedUntil);
break;
case $req->isPending():
echo 'Request appears next '; self::relativeDate($req->showAfter);
break;
default:
echo 'Answered '; self::relativeDate($req->history[0]->asOf);
} ?>
</em></small><?php
} ?>
</div><?php
} ?>
</div><?php