Finish req list, add snoozed list
This commit is contained in:
parent
2369827033
commit
d6e8cf66cc
|
@ -530,7 +530,7 @@ let routes = [
|
|||
routef "request/%s/add-notes" Components.addNotes // done
|
||||
routef "request/%s/item" Components.requestItem // not used
|
||||
routef "request/%s/notes" Components.notes // done
|
||||
routef "request/%s/snooze" Components.snooze
|
||||
routef "request/%s/snooze" Components.snooze // done
|
||||
]
|
||||
]
|
||||
GET_HEAD [ route "/docs" Home.docs ] // done
|
||||
|
@ -547,14 +547,14 @@ let routes = [
|
|||
routef "/%s/full" Request.getFull // done
|
||||
route "s/active" Request.active // done
|
||||
route "s/answered" Request.answered // done
|
||||
route "s/snoozed" Request.snoozed
|
||||
route "s/snoozed" Request.snoozed // done
|
||||
]
|
||||
PATCH [
|
||||
route "" Request.update // done
|
||||
routef "/%s/cancel-snooze" Request.cancelSnooze
|
||||
routef "/%s/prayed" Request.prayed // done
|
||||
routef "/%s/show" Request.show
|
||||
routef "/%s/snooze" Request.snooze
|
||||
routef "/%s/snooze" Request.snooze // done
|
||||
]
|
||||
POST [
|
||||
route "" Request.add // done
|
||||
|
|
|
@ -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 { ?>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
22
src/public/requests/snoozed.php
Normal file
22
src/public/requests/snoozed.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
use MyPrayerJournal\{Auth, Layout, Request, UI};
|
||||
|
||||
require '../../start.php';
|
||||
if ($_SERVER['REQUEST_METHOD'] <> 'GET') not_found();
|
||||
|
||||
Auth::requireUser();
|
||||
|
||||
$reqs = Request::snoozed();
|
||||
|
||||
Layout::pageHead('Snoozed Requests'); ?>
|
||||
<article class="container mt-3">
|
||||
<h2 class=pb-3>Snoozed Requests</h2><?php
|
||||
if ($reqs->hasItems()) {
|
||||
UI::requestList($reqs);
|
||||
} else {
|
||||
UI::noResults('No Snoozed Requests', '/journal', 'Return to your journal',
|
||||
'Your prayer journal has no snoozed requests');
|
||||
} ?>
|
||||
</article><?php
|
||||
Layout::pageFoot();
|
Loading…
Reference in New Issue
Block a user