Migrate v3 data; WIP on journal items
This commit is contained in:
		
							parent
							
								
									4aa6e832c7
								
							
						
					
					
						commit
						4ea55d4d25
					
				@ -1,3 +1,50 @@
 | 
				
			|||||||
<?php declare(strict_types=1);
 | 
					<?php declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO: write migration
 | 
					use BitBadger\PDODocument\{Configuration, Custom, Definition, Document, Mode};
 | 
				
			||||||
 | 
					use BitBadger\PDODocument\Mapper\ArrayMapper;
 | 
				
			||||||
 | 
					use MyPrayerJournal\{History, Note, Recurrence, RecurrencePeriod, Request, RequestAction, Table};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require 'start.php';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo 'Retrieving v3 requests...' . PHP_EOL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Configuration::resetPDO();
 | 
				
			||||||
 | 
					Configuration::$pdoDSN = 'pgsql:host=localhost;user=mpj;password=devpassword;dbname=mpj';
 | 
				
			||||||
 | 
					$reqs = Custom::array('SELECT data FROM mpj.request', [], new ArrayMapper());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo 'Found ' . sizeof($reqs) . ' requests; migrating to v4...' . PHP_EOL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Configuration::resetPDO();
 | 
				
			||||||
 | 
					Configuration::$mode   = Mode::SQLite;
 | 
				
			||||||
 | 
					Configuration::$pdoDSN = 'sqlite:./data/mpj.db';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Definition::ensureTable(Table::REQUEST);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					foreach ($reqs as $reqJson) {
 | 
				
			||||||
 | 
					    $req     = json_decode($reqJson['data']);
 | 
				
			||||||
 | 
					    $notes   = array_map(fn(stdClass $note) => new Note($note->asOf, $note->notes), $req->notes ?? []);
 | 
				
			||||||
 | 
					    $history = array_map(fn(stdClass $hist) =>
 | 
				
			||||||
 | 
					        new History(
 | 
				
			||||||
 | 
					            asOf:   $hist->asOf,
 | 
				
			||||||
 | 
					            action: RequestAction::from($hist->status),
 | 
				
			||||||
 | 
					            text:   property_exists($hist, 'text') ? $hist->text : null),
 | 
				
			||||||
 | 
					        $req->history);
 | 
				
			||||||
 | 
					    $recurParts  = explode(' ', $req->recurrence);
 | 
				
			||||||
 | 
					    $recurPeriod = RecurrencePeriod::from(end($recurParts));
 | 
				
			||||||
 | 
					    $recur       = match ($recurPeriod) {
 | 
				
			||||||
 | 
					        RecurrencePeriod::Immediate => new Recurrence(RecurrencePeriod::Immediate),
 | 
				
			||||||
 | 
					        default                     => new Recurrence($recurPeriod, (int)$recurParts[0])
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    $v4Req = new Request(
 | 
				
			||||||
 | 
					        id:           $req->id,
 | 
				
			||||||
 | 
					        enteredOn:    $req->enteredOn,
 | 
				
			||||||
 | 
					        userId:       $req->userId,
 | 
				
			||||||
 | 
					        snoozedUntil: property_exists($req, 'snoozedUntil') ? $req->snoozedUntil : null,
 | 
				
			||||||
 | 
					        showAfter:    property_exists($req, 'showAfter')    ? $req->showAfter    : null,
 | 
				
			||||||
 | 
					        recurrence:   $recur,
 | 
				
			||||||
 | 
					        history:      $history,
 | 
				
			||||||
 | 
					        notes:        $notes);
 | 
				
			||||||
 | 
					    Document::insert(Table::REQUEST, $v4Req);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo PHP_EOL . 'done' . PHP_EOL;
 | 
				
			||||||
 | 
				
			|||||||
@ -22,6 +22,16 @@ class Auth
 | 
				
			|||||||
        return self::$auth0;
 | 
					        return self::$auth0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Get the logged on user information
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return array|null The user information (null if no user is logged on)
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function user(): ?array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return self::client()->getUser();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Initiate a log on with Auth0
 | 
					     * Initiate a log on with Auth0
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
@ -50,4 +60,20 @@ class Auth
 | 
				
			|||||||
        header('Location: ' . self::client()->logout($_ENV['AUTH0_BASE_URL']));
 | 
					        header('Location: ' . self::client()->logout($_ENV['AUTH0_BASE_URL']));
 | 
				
			||||||
        exit;
 | 
					        exit;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Require a user be logged on
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param bool $redirect Whether to redirect to log on if there is not a user logged on
 | 
				
			||||||
 | 
					     * @return void If it returns, there is a user logged on; if not, we will be redirected to log on
 | 
				
			||||||
 | 
					     * @throws ConfigurationException If the Auth0 client is not configured correctly
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function requireUser(bool $redirect = true): void
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (is_null(self::user())) {
 | 
				
			||||||
 | 
					            if ($redirect) self::logOn();
 | 
				
			||||||
 | 
					            http_response_code(403);
 | 
				
			||||||
 | 
					            die('Not Authorized');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -2,10 +2,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace MyPrayerJournal;
 | 
					namespace MyPrayerJournal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use JsonSerializable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * A record of an action taken on a request
 | 
					 * A record of an action taken on a request
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class History
 | 
					class History implements JsonSerializable
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @param string $asOf The date/time this entry was made
 | 
					     * @param string $asOf The date/time this entry was made
 | 
				
			||||||
@ -13,4 +15,11 @@ class History
 | 
				
			|||||||
     * @param string|null $text The text for this history entry (optional)
 | 
					     * @param string|null $text The text for this history entry (optional)
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function __construct(public string $asOf, public RequestAction $action, public ?string $text = null) { }
 | 
					    public function __construct(public string $asOf, public RequestAction $action, public ?string $text = null) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function jsonSerialize(): mixed
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $values = ['asOf' => $this->asOf, 'action' => $this->action->value];
 | 
				
			||||||
 | 
					        if (!is_null($this->text)) $values['text'] = $this->text;
 | 
				
			||||||
 | 
					        return $values;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -114,4 +114,15 @@ class Layout
 | 
				
			|||||||
        </footer><?php
 | 
					        </footer><?php
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Create a card when there are no results found
 | 
				
			||||||
 | 
					    public static function noResults(string $heading, string $link, string $buttonText, string $text): void
 | 
				
			||||||
 | 
					    { ?>
 | 
				
			||||||
 | 
					        <div class=card>
 | 
				
			||||||
 | 
					            <h5 class=card-header><?=$heading?></h5>
 | 
				
			||||||
 | 
					            <div class="card-body text-center">
 | 
				
			||||||
 | 
					                <p class=card-text><?=$text?></p><?php
 | 
				
			||||||
 | 
					                page_link($link, $buttonText, ['class' => 'btn btn-primary']); ?>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div><?php
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -2,14 +2,23 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace MyPrayerJournal;
 | 
					namespace MyPrayerJournal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use JsonSerializable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * The recurrence for a prayer request
 | 
					 * The recurrence for a prayer request
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class Recurrence
 | 
					class Recurrence implements JsonSerializable
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @param RecurrencePeriod $period The recurrence period
 | 
					     * @param RecurrencePeriod $period The recurrence period
 | 
				
			||||||
     * @param int|null $interval How many of the periods will pass before the request is visible again
 | 
					     * @param int|null $interval How many of the periods will pass before the request is visible again
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function __construct(public RecurrencePeriod $period, public ?int $interval = null) { }
 | 
					    public function __construct(public RecurrencePeriod $period, public ?int $interval = null) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function jsonSerialize(): mixed
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $values = ['period' => $this->period->value];
 | 
				
			||||||
 | 
					        if (!is_null($this->interval)) $values['interval'] = $this->interval;
 | 
				
			||||||
 | 
					        return $values;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -5,17 +5,17 @@ namespace MyPrayerJournal;
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 * The type of recurrence a request can have
 | 
					 * The type of recurrence a request can have
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
enum RecurrencePeriod
 | 
					enum RecurrencePeriod: string
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /** Requests, once prayed, are available again immediately */
 | 
					    /** Requests, once prayed, are available again immediately */
 | 
				
			||||||
    case Immediate;
 | 
					    case Immediate = 'Immediate';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Requests, once prayed, appear again in a number of hours */
 | 
					    /** Requests, once prayed, appear again in a number of hours */
 | 
				
			||||||
    case Hours;
 | 
					    case Hours = 'Hours';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Requests, once prayed, appear again in a number of days */
 | 
					    /** Requests, once prayed, appear again in a number of days */
 | 
				
			||||||
    case Days;
 | 
					    case Days = 'Days';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Requests, once prayed, appear again in a number of weeks */
 | 
					    /** Requests, once prayed, appear again in a number of weeks */
 | 
				
			||||||
    case Weeks;
 | 
					    case Weeks = 'Weeks';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,12 +4,13 @@ namespace MyPrayerJournal;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use BitBadger\PDODocument\{DocumentException, Find};
 | 
					use BitBadger\PDODocument\{DocumentException, Find};
 | 
				
			||||||
use Exception;
 | 
					use Exception;
 | 
				
			||||||
 | 
					use JsonSerializable;
 | 
				
			||||||
use Visus\Cuid2\Cuid2;
 | 
					use Visus\Cuid2\Cuid2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * A prayer request
 | 
					 * A prayer request
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class Request
 | 
					class Request implements JsonSerializable
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @param string $id The ID for the request
 | 
					     * @param string $id The ID for the request
 | 
				
			||||||
@ -18,8 +19,8 @@ class Request
 | 
				
			|||||||
     * @param string|null $snoozedUntil The date/time the snooze expires for this request (null = not snoozed)
 | 
					     * @param string|null $snoozedUntil The date/time the snooze expires for this request (null = not snoozed)
 | 
				
			||||||
     * @param string|null $showAfter The date/time the current recurrence period is over (null = immediate)
 | 
					     * @param string|null $showAfter The date/time the current recurrence period is over (null = immediate)
 | 
				
			||||||
     * @param Recurrence $recurrence The recurrence for this request
 | 
					     * @param Recurrence $recurrence The recurrence for this request
 | 
				
			||||||
     * @param array|History[] $history The history of this request
 | 
					     * @param History[] $history The history of this request
 | 
				
			||||||
     * @param array|Note[] $notes Notes regarding this request
 | 
					     * @param Note[] $notes Notes regarding this request
 | 
				
			||||||
     * @throws Exception If the ID generation fails
 | 
					     * @throws Exception If the ID generation fails
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function __construct(public string $id = '', public string $enteredOn = '', public string $userId = '',
 | 
					    public function __construct(public string $id = '', public string $enteredOn = '', public string $userId = '',
 | 
				
			||||||
@ -44,4 +45,19 @@ class Request
 | 
				
			|||||||
        $req = Find::byId(Table::REQUEST, $id, self::class);
 | 
					        $req = Find::byId(Table::REQUEST, $id, self::class);
 | 
				
			||||||
        return ($req && $req->userId == $_SESSION['user_id']) ? $req : false;
 | 
					        return ($req && $req->userId == $_SESSION['user_id']) ? $req : false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function jsonSerialize(): mixed
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $values = [
 | 
				
			||||||
 | 
					            'id'         => $this->id,
 | 
				
			||||||
 | 
					            'enteredOn'  => $this->enteredOn,
 | 
				
			||||||
 | 
					            'userId'     => $this->userId,
 | 
				
			||||||
 | 
					            'recurrence' => $this->recurrence,
 | 
				
			||||||
 | 
					            'history'    => $this->history,
 | 
				
			||||||
 | 
					            'notes'      => $this->notes
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					        if (!is_null($this->snoozedUntil)) $values['snoozedUntil'] = $this->snoozedUntil;
 | 
				
			||||||
 | 
					        if (!is_null($this->showAfter))    $values['showAfter']    = $this->showAfter;
 | 
				
			||||||
 | 
					        return $values;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -5,17 +5,17 @@ namespace MyPrayerJournal;
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 * An action taken on a prayer request
 | 
					 * An action taken on a prayer request
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
enum RequestAction
 | 
					enum RequestAction: string
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /** The request was created */
 | 
					    /** The request was created */
 | 
				
			||||||
    case Created;
 | 
					    case Created = 'Created';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** The request was marked as having been prayed for */
 | 
					    /** The request was marked as having been prayed for */
 | 
				
			||||||
    case Prayed;
 | 
					    case Prayed = 'Prayed';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** The request was updated */
 | 
					    /** The request was updated */
 | 
				
			||||||
    case Updated;
 | 
					    case Updated = 'Updated';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** The request was marked as answered */
 | 
					    /** The request was marked as answered */
 | 
				
			||||||
    case Answered;
 | 
					    case Answered = 'Answered';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										64
									
								
								src/public/components/journal-items.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/public/components/journal-items.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,64 @@
 | 
				
			|||||||
 | 
					<?php declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use BitBadger\PDODocument\{Custom, Query};
 | 
				
			||||||
 | 
					use BitBadger\PDODocument\Mapper\DocumentMapper;
 | 
				
			||||||
 | 
					use MyPrayerJournal\{Auth,History,Layout,Request,Table};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require '../../start.php';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Auth::requireUser(false);
 | 
				
			||||||
 | 
					bare_head();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$reqs = Custom::list(
 | 
				
			||||||
 | 
					    Query::selectFromTable(Table::REQUEST) . " WHERE data->>'userId' = :userId AND data->>'$.history[0].action' <> 'Answered'",
 | 
				
			||||||
 | 
					    [':userId' => Auth::user()['sub']], new DocumentMapper(Request::class));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if ($reqs->hasItems()) { ?>
 | 
				
			||||||
 | 
					    <section id=journalItems class="row row-cols-1 row-cols-md-2 row-cols-lg-3 row-cols-xl-4 g-3" hx-target=this
 | 
				
			||||||
 | 
					             hx-swap=outerHTML aria-label="Prayer Requests"><?php
 | 
				
			||||||
 | 
					        $spacer = '<span> </span>';
 | 
				
			||||||
 | 
					        foreach ($reqs->items() as /** @var Request $req */ $req) {
 | 
				
			||||||
 | 
					            $withText = array_filter($req->history, fn($hist) => isset($hist->text));
 | 
				
			||||||
 | 
					            $text = $withText[array_key_first($withText)]->text; ?>
 | 
				
			||||||
 | 
					            <div class=col>
 | 
				
			||||||
 | 
					                <div class="card h-100">
 | 
				
			||||||
 | 
					                    <div class="card-header p-0 d-flex" role=toolbar><?php
 | 
				
			||||||
 | 
					                        page_link("/request/edit?id=$req->id", icon('edit'),
 | 
				
			||||||
 | 
					                            ['class' => 'btn btn-secondary', 'title' => 'Edit Request']); ?>
 | 
				
			||||||
 | 
					                        <?=$spacer?>
 | 
				
			||||||
 | 
					                        <button type=button class="btn btn-secondary" title="Add Notes" data-bs-toggle=modal
 | 
				
			||||||
 | 
					                                data-bs-target=#notesModal hx-get="/components/request/add-notes?id=<?=$req->id?>"
 | 
				
			||||||
 | 
					                                hx-target=#notesBody hx-swap=innerHTML><?=icon('comment');?></button>
 | 
				
			||||||
 | 
					                        <?=$spacer?>
 | 
				
			||||||
 | 
					                        <button type=button class="btn btn-secondary" title="Snooze Request" data-bs-toggle=modal
 | 
				
			||||||
 | 
					                                data-bs-target=#snoozeModal hx-get="/components/request/snooze?id=<?=$req->id?>"
 | 
				
			||||||
 | 
					                                hx-target=#snoozeBody hx-swap=innerHTML><?=icon('schedule');?></button>
 | 
				
			||||||
 | 
					                        <div class=flex-grow-1></div>
 | 
				
			||||||
 | 
					                        <button type=button class="btn btn-success w-25" hx-patch="/request/prayed?id=<?=$req->id?>"
 | 
				
			||||||
 | 
					                                title="Mark as Prayed"><?=icon('done');?></button>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <div class=card-body>
 | 
				
			||||||
 | 
					                        <p class=request-text><?=htmlentities($text);?>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <div class="card-footer text-end text-muted px-1 py-0">
 | 
				
			||||||
 | 
					                        <em>last activity <?=$req->history[0]->asOf?></em>
 | 
				
			||||||
 | 
					                        <?php /*
 | 
				
			||||||
 | 
					 TODO: relative time
 | 
				
			||||||
 | 
					  [] [
 | 
				
			||||||
 | 
					            match req.LastPrayed with
 | 
				
			||||||
 | 
					            | Some dt -> str "last prayed ";   relativeDate dt       now tz
 | 
				
			||||||
 | 
					            | None    -> str "last activity "; relativeDate req.AsOf now tz
 | 
				
			||||||
 | 
					            ] */ ?>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div><?php
 | 
				
			||||||
 | 
					        } ?>
 | 
				
			||||||
 | 
					    </section><?php
 | 
				
			||||||
 | 
					} else {
 | 
				
			||||||
 | 
					    Layout::noResults('No Active Requests', '/request/edit?id=new', 'Add a Request', <<<'TEXT'
 | 
				
			||||||
 | 
					        You have no requests to be shown; see the “Active” link above for snoozed or deferred requests, and
 | 
				
			||||||
 | 
					        the “Answered” link for answered requests
 | 
				
			||||||
 | 
					        TEXT);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bare_foot();
 | 
				
			||||||
							
								
								
									
										48
									
								
								src/public/journal.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/public/journal.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,48 @@
 | 
				
			|||||||
 | 
					<?php declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use MyPrayerJournal\Auth;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require '../start.php';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Auth::requireUser();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$user = Auth::user();
 | 
				
			||||||
 | 
					$name = $user['first_name'] ?? 'Your';
 | 
				
			||||||
 | 
					page_head('Welcome'); ?>
 | 
				
			||||||
 | 
					<article class="container-fluid mt-3">
 | 
				
			||||||
 | 
					    <h2 class=pb-3><?=$name?><?=$name == 'Your' ? '' : '’s'?> Prayer Journal</h2>
 | 
				
			||||||
 | 
					    <p class="pb-3 text-center"><?php
 | 
				
			||||||
 | 
					        page_link('/request/new/edit', icon('add_box') . ' Add a Prayer Request', ['class' => 'btn btn-primary']); ?>
 | 
				
			||||||
 | 
					    <p hx-get=/components/journal-items hx-swap=outerHTML hx-trigger=load hx-target=this>
 | 
				
			||||||
 | 
					        Loading your prayer journal…
 | 
				
			||||||
 | 
					    <div id=notesModal class="modal fade" tabindex=-1 aria-labelledby=nodesModalLabel aria-hidden=true>
 | 
				
			||||||
 | 
					        <div class="modal-dialog modal-dialog-scrollable">
 | 
				
			||||||
 | 
					            <div class=modal-content>
 | 
				
			||||||
 | 
					                <div class=modal-header>
 | 
				
			||||||
 | 
					                    <h5 class=modal-title id=nodesModalLabel>Add Notes to Prayer Request</h5>
 | 
				
			||||||
 | 
					                    <button type=button class=btn-close data-bs-dismiss=modal aria-label=Close></button>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <div class=modal-body id=notesBody></div>
 | 
				
			||||||
 | 
					                <div class=modal-footer>
 | 
				
			||||||
 | 
					                    <button type=button id=notesDismiss class="btn btn-secondary" data-bs-dismiss=modal>Close</button>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div id=snoozeModal class="modal fade" tabindex=-1 aria-labelledby=snoozeModalLabel aria-hidden=true>
 | 
				
			||||||
 | 
					        <div class="modal-dialog modal-sm">
 | 
				
			||||||
 | 
					            <div class=modal-content>
 | 
				
			||||||
 | 
					                <div class=modal-header>
 | 
				
			||||||
 | 
					                    <h5 class=modal-title id=snoozeModalLabel>Snooze Prayer Request</h5>
 | 
				
			||||||
 | 
					                    <button type=button class=btn-close data-bs-dismiss=modal aria-label=Close></button>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <div class=modal-body id=snoozeBody></div>
 | 
				
			||||||
 | 
					                <div class=modal-footer>
 | 
				
			||||||
 | 
					                    <button type=button id=snoozeDismiss class="btn btn-secondary" data-bs-dismiss=modal>Close</button>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</article><?php
 | 
				
			||||||
 | 
					page_foot();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -7,5 +7,5 @@ require '../../../start.php';
 | 
				
			|||||||
Auth::client()->exchange($_ENV['AUTH0_BASE_URL'] . '/user/log-on/success');
 | 
					Auth::client()->exchange($_ENV['AUTH0_BASE_URL'] . '/user/log-on/success');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO: get the possible redirect URL
 | 
					// TODO: get the possible redirect URL
 | 
				
			||||||
header('Location: /');
 | 
					header('Location: /journal');
 | 
				
			||||||
exit();
 | 
					exit();
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,8 @@
 | 
				
			|||||||
<?php declare(strict_types=1);
 | 
					<?php declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use BitBadger\PDODocument\{Configuration, Definition, Mode};
 | 
				
			||||||
use Dotenv\Dotenv;
 | 
					use Dotenv\Dotenv;
 | 
				
			||||||
use MyPrayerJournal\{Auth, Layout};
 | 
					use MyPrayerJournal\{Auth, Layout, Table};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require __DIR__ . '/vendor/autoload.php';
 | 
					require __DIR__ . '/vendor/autoload.php';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -16,6 +17,10 @@ if (!is_null($auth0_session)) {
 | 
				
			|||||||
    $_SESSION['user_id'] = $auth0_session->user['sub'];
 | 
					    $_SESSION['user_id'] = $auth0_session->user['sub'];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Configuration::$pdoDSN = 'sqlite:' . implode(DIRECTORY_SEPARATOR, [__DIR__, 'data', 'mpj.db']);
 | 
				
			||||||
 | 
					Configuration::$mode   = Mode::SQLite;
 | 
				
			||||||
 | 
					Definition::ensureTable(Table::REQUEST);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Is this an htmx request?
 | 
					 * Is this an htmx request?
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@ -33,6 +38,16 @@ function page_link(string $href, string $text, array $attrs = []): void
 | 
				
			|||||||
    echo ">$text</a>";
 | 
					    echo ">$text</a>";
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Generate a material icon
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param string $name The name of the material icon
 | 
				
			||||||
 | 
					 * @return string The material icon wrapped in a `span` tag
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function icon(string $name): string {
 | 
				
			||||||
 | 
					    return "<span class=material-icons>$name</span>";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function page_head(string $title): void
 | 
					function page_head(string $title): void
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Layout::htmlHead($title);
 | 
					    Layout::htmlHead($title);
 | 
				
			||||||
@ -42,6 +57,11 @@ function page_head(string $title): void
 | 
				
			|||||||
    echo '<main role=main>';
 | 
					    echo '<main role=main>';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function bare_head(): void
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    echo '<!DOCTYPE html><html lang=en><head><title></title></head><body>';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function page_foot(): void
 | 
					function page_foot(): void
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    echo '</main>';
 | 
					    echo '</main>';
 | 
				
			||||||
@ -51,3 +71,8 @@ function page_foot(): void
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    echo '</body></html>';
 | 
					    echo '</body></html>';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function bare_foot(): void
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    echo '</body></html>';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user