Add request edit form
- Add partial output template - Group routes
This commit is contained in:
parent
00034c0a26
commit
817d7876db
|
@ -95,4 +95,27 @@ class AppUser
|
|||
{
|
||||
return self::auth0Instance()->getCredentials();
|
||||
}
|
||||
|
||||
/**
|
||||
* Require that there be a user logged on
|
||||
*
|
||||
* @return void This will not return if there is not a user logged on
|
||||
*/
|
||||
public static function require()
|
||||
{
|
||||
if (is_null(self::current())) {
|
||||
// TODO: get the current URL to specify for redirection
|
||||
self::logOn();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID (`sub`) for the current user
|
||||
*
|
||||
* @return string The ID of the user (blank string if there is no current user)
|
||||
*/
|
||||
public static function currentId(): string
|
||||
{
|
||||
return self::auth0Instance()->getCredentials()?->user['sub'] ?? '';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -137,4 +137,17 @@ class Data
|
|||
usort($reqs, AsOf::oldestToNewest(...));
|
||||
return $reqs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to obtain a journal request by its ID
|
||||
*
|
||||
* @param string $reqId The request ID
|
||||
* @param string $userId The ID of the currently logged-on user
|
||||
* @return ?JournalRequest The request, or null if it is not found
|
||||
*/
|
||||
public static function tryJournalById(string $reqId, string $userId): ?JournalRequest
|
||||
{
|
||||
$req = self::findFullRequestById($reqId, $userId);
|
||||
return is_null($req) ? null : new JournalRequest($req);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ declare(strict_types=1);
|
|||
|
||||
namespace MyPrayerJournal;
|
||||
|
||||
use MyPrayerJournal\Domain\JournalRequest;
|
||||
|
||||
class Handlers
|
||||
{
|
||||
/**
|
||||
|
@ -23,8 +25,8 @@ class Handlers
|
|||
'hasSnoozed' => false,
|
||||
]);
|
||||
$params['pageContent'] = app()->template->render($template, $params);
|
||||
// TODO: make the htmx distinction here
|
||||
response()->markup(app()->template->render('layout/full', $params));
|
||||
$layout = $params['isHtmx'] ? 'layout/partial' : 'layout/full';
|
||||
response()->markup(app()->template->render($layout, $params));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -41,10 +43,18 @@ class Handlers
|
|||
response()->markup(app()->template->render('layout/component', $params));
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a 404 Not Found response
|
||||
*/
|
||||
private static function notFound()
|
||||
{
|
||||
response()->plain('Not found', 404);
|
||||
}
|
||||
|
||||
/** GET: /journal */
|
||||
public static function journal()
|
||||
{
|
||||
if (!AppUser::current()) AppUser::logOn();
|
||||
AppUser::require();
|
||||
|
||||
$user = AppUser::current()->user;
|
||||
$firstName = (array_key_exists('given_name', $user) ? $user['given_name'] : null) ?? 'Your';
|
||||
|
@ -54,10 +64,47 @@ class Handlers
|
|||
/** GET: /components/journal-items */
|
||||
public static function journalItems()
|
||||
{
|
||||
if (!AppUser::current()) AppUser::logOn();
|
||||
AppUser::require();
|
||||
|
||||
self::renderComponent('components/journal_items', [
|
||||
'requests' => Data::getJournal(AppUser::current()->user['sub'])
|
||||
]);
|
||||
$reqs = Data::getJournal(AppUser::currentId());
|
||||
$utc = new \DateTimeZone('Etc/UTC');
|
||||
$now = date_create_immutable(timezone: $utc);
|
||||
$epoch = date_create_immutable('1970-01-01', $utc);
|
||||
array_filter($reqs,
|
||||
fn (JournalRequest $req) => $req->snoozedUntil ?? $epoch < $now && $req->showAfter ?? $epoch < $now);
|
||||
|
||||
self::renderComponent('components/journal_items', [ 'requests' => $reqs ]);
|
||||
}
|
||||
|
||||
/** GET /request/[req-id]/edit */
|
||||
public static function requestEdit(string $reqId)
|
||||
{
|
||||
AppUser::require();
|
||||
|
||||
$returnTo = array_key_exists('HTTP_REFERER', $_SERVER)
|
||||
? match (true) {
|
||||
str_ends_with($_SERVER['HTTP_REFERER'], '/active') => 'active',
|
||||
str_ends_with($_SERVER['HTTP_REFERER'], '/snoozed') => 'snoozed',
|
||||
default => 'journal'
|
||||
}
|
||||
: 'journal';
|
||||
if ($reqId == 'new') {
|
||||
self::render('requests/edit', 'Add Prayer Request', [
|
||||
'request' => new JournalRequest(),
|
||||
'isNew' => true,
|
||||
'returnTo' => $returnTo,
|
||||
]);
|
||||
} else {
|
||||
$req = Data::tryJournalById($reqId, AppUser::currentId());
|
||||
if (is_null($req)) {
|
||||
self::notFound();
|
||||
} else {
|
||||
self::render('requests/edit', 'Edit Prayer Request', [
|
||||
'request' => $req,
|
||||
'isNew' => false,
|
||||
'returnTo' => $returnTo,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,19 +19,24 @@ app()->template->config('params', [
|
|||
'version' => 'v4',
|
||||
]);
|
||||
|
||||
|
||||
app()->get('/', fn () => Handlers::render('home', 'Welcome'));
|
||||
|
||||
app()->get('/components/journal-items', Handlers::journalItems(...));
|
||||
|
||||
app()->group('/components', function () {
|
||||
app()->get('/journal-items', Handlers::journalItems(...));
|
||||
});
|
||||
app()->get('/journal', Handlers::journal(...));
|
||||
|
||||
app()->get('/legal/privacy-policy', fn () => Handlers::render('legal/privacy-policy', 'Privacy Policy'));
|
||||
app()->get('/legal/terms-of-service', fn () => Handlers::render('legal/terms-of-service', 'Terms of Service'));
|
||||
|
||||
app()->get('/user/log-on', AppUser::logOn(...));
|
||||
app()->get('/user/log-on/success', AppUser::processLogOn(...));
|
||||
app()->get('/user/log-off', AppUser::logOff(...));
|
||||
app()->group('/legal', function () {
|
||||
app()->get('/privacy-policy', fn () => Handlers::render('legal/privacy-policy', 'Privacy Policy'));
|
||||
app()->get('/terms-of-service', fn () => Handlers::render('legal/terms-of-service', 'Terms of Service'));
|
||||
});
|
||||
app()->group('/request', function () {
|
||||
app()->get('/{reqId}/edit', Handlers::requestEdit(...));
|
||||
});
|
||||
app()->group('/user', function () {
|
||||
app()->get('/log-on', AppUser::logOn(...));
|
||||
app()->get('/log-on/success', AppUser::processLogOn(...));
|
||||
app()->get('/log-off', AppUser::logOff(...));
|
||||
});
|
||||
|
||||
// TODO: remove before go-live
|
||||
$stdOut = fopen('php://stdout', 'w');
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<body>
|
||||
<section id="top" aria-label="Top navigation">
|
||||
<?php echo app()->template->render('layout/_nav', [ 'user' => $user, 'hasSnoozed' => $hasSnoozed ]); ?>
|
||||
<?php echo $pageContent; ?>
|
||||
<main role="main"><?php echo $pageContent; ?></main>
|
||||
</section>
|
||||
<?php echo app()->template->render('layout/_foot', [ 'isHtmx' => $isHtmx ]); ?>
|
||||
</body>
|
||||
|
|
12
src/app/pages/layout/partial.view.php
Normal file
12
src/app/pages/layout/partial.view.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title><?php echo $pageTitle; ?> « myPrayerJournal</title>
|
||||
</head>
|
||||
<body>
|
||||
<section id="top" aria-label="Top navigation">
|
||||
<?php echo app()->template->render('layout/_nav', [ 'user' => $user, 'hasSnoozed' => $hasSnoozed ]); ?>
|
||||
<main role="main"><?php echo $pageContent; ?></main>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
85
src/app/pages/requests/edit.view.php
Normal file
85
src/app/pages/requests/edit.view.php
Normal file
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
use MyPrayerJournal\Domain\RecurrenceType;
|
||||
|
||||
$cancelLink = match ($returnTo) {
|
||||
'active' => '/requests/active',
|
||||
'snoozed' => '/requests/snoozed',
|
||||
default => '/journal',
|
||||
};
|
||||
$isImmediate = $request->recurrenceType == RecurrenceType::Immediate;
|
||||
$isHours = $request->recurrenceType == RecurrenceType::Hours;
|
||||
$isDays = $request->recurrenceType == RecurrenceType::Days;
|
||||
$isWeeks = $request->recurrenceType == RecurrenceType::Weeks; ?>
|
||||
<article class="container">
|
||||
<h2 class="pb-3"><?php echo $isNew ? 'Add' : 'Edit'; ?> Prayer Request</h2>
|
||||
<form hx-boost="true" hx-target="#top" hx-push-url="true"
|
||||
<?php echo $isNew ? 'hx-post' : 'hx-patch'; ?>="/request">
|
||||
<input type="hidden" name="requestId" value="<?php echo $isNew ? 'new' : $request->id; ?>">
|
||||
<input type="hidden" name="returnTo" value="<?php echo $returnTo; ?>">
|
||||
<div class="form-floating pb-3">
|
||||
<textarea id="requestText" name="requestText" class="form-control" style="min-height: 8rem;"
|
||||
placeholder="Enter the text of the request"
|
||||
autofocus required><?php echo $request->text; ?></textarea>
|
||||
<label for="requestText">Prayer Request</label>
|
||||
</div><br><?php
|
||||
if (!$isNew) { ?>
|
||||
<div class="pb-3">
|
||||
<label>Also Mark As</label><br>
|
||||
<div class="form-check form-check-inline">
|
||||
<input type="radio" class="form-check-input" id="sU" name="status" value="Updated" checked>
|
||||
<label for="sU">Updated</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input type="radio" class="form-check-input" id="sP" name="status" value="Prayed">
|
||||
<label for="sP">Prayed</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input type="radio" class="form-check-input" id="sA" name="status" value="Answered">
|
||||
<label for="sA">Answered</label>
|
||||
</div>
|
||||
</div><?php
|
||||
} ?>
|
||||
<div class="row">
|
||||
<div class="col-12 offset-md-2 col-md-8 offset-lg-3 col-lg-6">
|
||||
<p>
|
||||
<strong>Recurrence</strong>
|
||||
<em class="text-muted">After prayer, request reappears…</em>
|
||||
</p>
|
||||
<div class="d-flex flex-row flex-wrap justify-content-center align-items-center">
|
||||
<div class="form-check mx-2">
|
||||
<input type="radio" class="form-check-input" id="rI" name="recurType" value="Immediate"
|
||||
onclick="mpj.edit.toggleRecurrence(event)" <?php echo $isImmediate ? 'checked' : ''; ?>>
|
||||
<label for="rI">Immediately</label>
|
||||
</div>
|
||||
<div class="form-check mx-2">
|
||||
<input type="radio" class="form-check-input" id="rO" name="recurType" value="Other"
|
||||
onclick="mpj.edit.toggleRecurrence(event)" <?php echo $isImmediate ? '' : 'checked'; ?>>
|
||||
<label for="rO">Every…</label>
|
||||
</div>
|
||||
<div class="form-floating mx-2">
|
||||
<input type="number" class="form-control" id="recurCount" name="recurCount" placeholder="0"
|
||||
value="<?php echo $request->recurrence ?? 0; ?>" style="width:6rem;" required
|
||||
<?php echo $isImmediate ? 'disabled' : ''; ?>>
|
||||
<label for="recurCount">Count</label>
|
||||
</div>
|
||||
<div class="form-floating mx-2">
|
||||
<select class="form-control" id="recurInterval" name="recurInterval" style="width:6rem;"
|
||||
required <?php echo $isImmediate ? 'disabled' : ''; ?>>
|
||||
<option value="Hours" <?php echo $isHours ? 'selected' : ''; ?>>hours</option>
|
||||
<option value="Days" <?php echo $isDays ? 'selected' : ''; ?>>days</option>
|
||||
<option value="Weeks" <?php echo $isWeeks ? 'selected' : ''; ?>>weeks</option>
|
||||
</select>
|
||||
<label for="recurInterval">Interval</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-end pt-3">
|
||||
<button class="btn btn-primary me-2" type="submit"><span class="material-icons">save</span> Save</button>
|
||||
<a <?php $page_link($cancelLink); ?> class="btn btn-secondary ms-2">
|
||||
<span class="material-icons">arrow_back</span> Cancel
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</article>
|
Loading…
Reference in New Issue
Block a user