Compare commits
48 Commits
Author | SHA1 | Date | |
---|---|---|---|
82700e2dc5 | |||
8aa1652283 | |||
16d5df4095 | |||
885298437b | |||
8cf8d82443 | |||
37f3ade420 | |||
258ff9eda7 | |||
2c9511ecf4 | |||
97d656912c | |||
717b9398bc | |||
6a070ca4e0 | |||
fa8ef2ab78 | |||
20dc1622f2 | |||
fbf5ac564a | |||
d24c304c97 | |||
752b2a291e | |||
87fb461c26 | |||
70e9ef508c | |||
fba8454743 | |||
da5e3b538d | |||
c2c08db342 | |||
4d55711190 | |||
164ed62a48 | |||
bdc67942ea | |||
4a6191e287 | |||
d809e7eb38 | |||
83709509f2 | |||
7bb909dfe4 | |||
1d98940341 | |||
14b4ca0545 | |||
ea60cf2622 | |||
53e5c48aa9 | |||
a1e921063a | |||
2552335513 | |||
74b24afc75 | |||
451a61722e | |||
a46253ec7d | |||
45a3398ac7 | |||
a20caf1fc8 | |||
435402ee41 | |||
8315970571 | |||
d26874d88b | |||
d1ac0578f3 | |||
3d10944b6d | |||
72bf4273f3 | |||
77e2777c7a | |||
a1f5ce416c | |||
6af0095470 |
@ -1,4 +1,4 @@
|
|||||||
FROM php:8.2-apache
|
FROM php:8.3-apache
|
||||||
|
|
||||||
RUN apt update && \
|
RUN apt update && \
|
||||||
apt upgrade -y && \
|
apt upgrade -y && \
|
||||||
@ -45,10 +45,13 @@ RUN rm -rf /var/www/html/tests
|
|||||||
RUN rm -rf /var/www/html/translations
|
RUN rm -rf /var/www/html/translations
|
||||||
|
|
||||||
RUN COMPOSER_ALLOW_SUPERUSER=1 composer install --no-scripts --no-dev --optimize-autoloader
|
RUN COMPOSER_ALLOW_SUPERUSER=1 composer install --no-scripts --no-dev --optimize-autoloader
|
||||||
RUN mv /var/www/html/data/data.db /var/www/html/var/
|
RUN mkdir /data
|
||||||
|
RUN chown -R 33:33 /data
|
||||||
|
RUN chmod -R 755 /data
|
||||||
|
COPY data/data.db /data/data.db
|
||||||
|
|
||||||
RUN mkdir /var/www/html/var/cache
|
RUN mkdir /var/www/html/var/cache
|
||||||
RUN mkdir /var/www/html/var/log
|
RUN mkdir /var/www/html/var/log
|
||||||
|
|
||||||
RUN chown -R www-data:www-data /var/www/html
|
RUN chown -R 33:33 /var/www/html
|
||||||
RUN chmod -R 755 /var/www/html
|
RUN chmod -R 755 /var/www/html
|
@ -12,11 +12,13 @@
|
|||||||
"doctrine/doctrine-bundle": "^2.12",
|
"doctrine/doctrine-bundle": "^2.12",
|
||||||
"doctrine/doctrine-migrations-bundle": "^3.3",
|
"doctrine/doctrine-migrations-bundle": "^3.3",
|
||||||
"doctrine/orm": "^3.1",
|
"doctrine/orm": "^3.1",
|
||||||
|
"erusev/parsedown": "^1.7",
|
||||||
"phpdocumentor/reflection-docblock": "^5.4",
|
"phpdocumentor/reflection-docblock": "^5.4",
|
||||||
"phpstan/phpdoc-parser": "^1.28",
|
"phpstan/phpdoc-parser": "^1.28",
|
||||||
"symfony/asset": "7.0.*",
|
"symfony/asset": "7.0.*",
|
||||||
"symfony/asset-mapper": "7.0.*",
|
"symfony/asset-mapper": "7.0.*",
|
||||||
"symfony/console": "7.0.*",
|
"symfony/console": "7.0.*",
|
||||||
|
"symfony/debug-bundle": "7.0.*",
|
||||||
"symfony/doctrine-messenger": "7.0.*",
|
"symfony/doctrine-messenger": "7.0.*",
|
||||||
"symfony/dotenv": "7.0.*",
|
"symfony/dotenv": "7.0.*",
|
||||||
"symfony/expression-language": "7.0.*",
|
"symfony/expression-language": "7.0.*",
|
||||||
@ -45,8 +47,7 @@
|
|||||||
"symfony/web-link": "7.0.*",
|
"symfony/web-link": "7.0.*",
|
||||||
"symfony/yaml": "7.0.*",
|
"symfony/yaml": "7.0.*",
|
||||||
"twig/extra-bundle": "^2.12|^3.0",
|
"twig/extra-bundle": "^2.12|^3.0",
|
||||||
"twig/twig": "^2.12|^3.0",
|
"twig/twig": "^2.12|^3.0"
|
||||||
"symfony/debug-bundle": "7.0.*"
|
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"allow-plugins": {
|
"allow-plugins": {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
framework:
|
framework:
|
||||||
mailer:
|
mailer:
|
||||||
dsn: '%env(MAILER_DSN)%'
|
dsn: "%env(MAILER_DSN)%"
|
||||||
|
message_bus: false
|
||||||
|
BIN
data/data.db
BIN
data/data.db
Binary file not shown.
@ -6,3 +6,5 @@ services:
|
|||||||
image: ryanprather/sermon-notes:latest
|
image: ryanprather/sermon-notes:latest
|
||||||
ports:
|
ports:
|
||||||
- 80:80
|
- 80:80
|
||||||
|
volumes:
|
||||||
|
- ./data:/data
|
@ -10,8 +10,10 @@ LENGTH=32
|
|||||||
SECRET_KEY=$(openssl rand -base64 $LENGTH | tr -d '=' | tr -d '+' | tr -d '/' | tr -d ' ')
|
SECRET_KEY=$(openssl rand -base64 $LENGTH | tr -d '=' | tr -d '+' | tr -d '/' | tr -d ' ')
|
||||||
TRIMMED_KEY=$(cut -c1-32 <<< $SECRET_KEY)
|
TRIMMED_KEY=$(cut -c1-32 <<< $SECRET_KEY)
|
||||||
echo "APP_SECRET=$TRIMMED_KEY" >> .env
|
echo "APP_SECRET=$TRIMMED_KEY" >> .env
|
||||||
echo "DATABASE_URL=\"sqlite:///%kernel.project_dir%/var/data.db\"" >> .env
|
echo "DATABASE_URL=\"sqlite:///data/data.db\"" >> .env
|
||||||
echo "MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0" >> .env
|
echo "MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0" >> .env
|
||||||
|
|
||||||
symfony console doctrine:migrations:migrate --no-interaction
|
|
||||||
COMPOSER_ALLOW_SUPERUSER=1 composer update
|
COMPOSER_ALLOW_SUPERUSER=1 composer update
|
||||||
|
symfony console doctrine:migrations:migrate --no-interaction
|
||||||
|
|
||||||
|
chown -R www-data:www-data /data
|
||||||
|
43
migrations/Version20240527010736.php
Normal file
43
migrations/Version20240527010736.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20240527010736 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('ALTER TABLE note ADD COLUMN recording VARCHAR(255) DEFAULT NULL');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__note AS SELECT id, speaker_id, series_id, user_id, title, date, passage, refs, text FROM note');
|
||||||
|
$this->addSql('DROP TABLE note');
|
||||||
|
$this->addSql('CREATE TABLE note (id BLOB NOT NULL --(DC2Type:uuid)
|
||||||
|
, speaker_id BLOB DEFAULT NULL --(DC2Type:uuid)
|
||||||
|
, series_id BLOB DEFAULT NULL --(DC2Type:uuid)
|
||||||
|
, user_id BLOB DEFAULT NULL --(DC2Type:uuid)
|
||||||
|
, title VARCHAR(255) NOT NULL, date DATE NOT NULL, passage VARCHAR(255) NOT NULL, refs CLOB DEFAULT NULL --(DC2Type:json)
|
||||||
|
, text CLOB DEFAULT NULL, PRIMARY KEY(id), CONSTRAINT FK_CFBDFA14D04A0F27 FOREIGN KEY (speaker_id) REFERENCES speaker (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_CFBDFA145278319C FOREIGN KEY (series_id) REFERENCES series (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_CFBDFA14A76ED395 FOREIGN KEY (user_id) REFERENCES user (id) NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO note (id, speaker_id, series_id, user_id, title, date, passage, refs, text) SELECT id, speaker_id, series_id, user_id, title, date, passage, refs, text FROM __temp__note');
|
||||||
|
$this->addSql('DROP TABLE __temp__note');
|
||||||
|
$this->addSql('CREATE INDEX IDX_CFBDFA14D04A0F27 ON note (speaker_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_CFBDFA145278319C ON note (series_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_CFBDFA14A76ED395 ON note (user_id)');
|
||||||
|
}
|
||||||
|
}
|
38
migrations/Version20240622233923.php
Normal file
38
migrations/Version20240622233923.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20240622233923 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('ALTER TABLE user ADD COLUMN meta_data CLOB DEFAULT NULL');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__user AS SELECT id, email, roles, password, name FROM user');
|
||||||
|
$this->addSql('DROP TABLE user');
|
||||||
|
$this->addSql('CREATE TABLE user (id BLOB NOT NULL --(DC2Type:uuid)
|
||||||
|
, email VARCHAR(180) NOT NULL, roles CLOB NOT NULL --(DC2Type:json)
|
||||||
|
, password VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
|
||||||
|
$this->addSql('INSERT INTO user (id, email, roles, password, name) SELECT id, email, roles, password, name FROM __temp__user');
|
||||||
|
$this->addSql('DROP TABLE __temp__user');
|
||||||
|
$this->addSql('CREATE UNIQUE INDEX UNIQ_IDENTIFIER_EMAIL ON user (email)');
|
||||||
|
}
|
||||||
|
}
|
@ -18,7 +18,7 @@ body {
|
|||||||
|
|
||||||
.ref-tab {
|
.ref-tab {
|
||||||
width: 60px;
|
width: 60px;
|
||||||
padding-top: 75px !important;
|
padding-top: 55px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ref-tab ul {
|
.ref-tab ul {
|
||||||
@ -43,24 +43,12 @@ body {
|
|||||||
height: 80px;
|
height: 80px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: #f56a6a;
|
|
||||||
color: #fff !important;
|
|
||||||
border: none;
|
|
||||||
border-radius: 3px;
|
|
||||||
box-shadow: 0 4px 5px rgba(0, 0, 0, 0.8);
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
margin-bottom: 3px;
|
margin-bottom: 3px;
|
||||||
}
|
}
|
||||||
.tab button:active {
|
|
||||||
background-color: #7a0016;
|
|
||||||
}
|
|
||||||
|
|
||||||
.activeRef {
|
|
||||||
background-color: #3e8e41 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ref {
|
.ref {
|
||||||
width: 35%;
|
width: 36%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ref > div#ref {
|
.ref > div#ref {
|
||||||
@ -76,7 +64,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ref {
|
#ref {
|
||||||
padding: 3px 3px 3px 10px;
|
padding: 3px 3px 3px 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#passage {
|
#passage {
|
||||||
@ -102,7 +90,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.notes {
|
.notes {
|
||||||
width: 55%;
|
width: 57%;
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea#notes {
|
textarea#notes {
|
||||||
@ -114,10 +102,18 @@ textarea#notes {
|
|||||||
#notePreview {
|
#notePreview {
|
||||||
display: none;
|
display: none;
|
||||||
overflow-x: scroll;
|
overflow-x: scroll;
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#notePreview ul,
|
||||||
|
#notePreview ol {
|
||||||
|
list-style-position: inside;
|
||||||
}
|
}
|
||||||
|
|
||||||
#previewBtn.active,
|
#previewBtn.active,
|
||||||
#show-hide-btn.active {
|
#show-hide-btn.active,
|
||||||
|
.tab button.active,
|
||||||
|
#openRefBtn.active {
|
||||||
background-color: #f56a6a !important;
|
background-color: #f56a6a !important;
|
||||||
color: white !important;
|
color: white !important;
|
||||||
}
|
}
|
||||||
@ -140,6 +136,8 @@ textarea#notes {
|
|||||||
|
|
||||||
#note-list {
|
#note-list {
|
||||||
display: none;
|
display: none;
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
#note-list ul {
|
#note-list ul {
|
||||||
@ -205,7 +203,7 @@ div#refQuery #referenceSearch {
|
|||||||
|
|
||||||
#fields-container input,
|
#fields-container input,
|
||||||
#fields-container select {
|
#fields-container select {
|
||||||
width: 19.5%;
|
width: 32.5%;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,6 +232,65 @@ div#refQuery #referenceSearch {
|
|||||||
font-size: 12pt;
|
font-size: 12pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ref ol,
|
||||||
|
#ref ul {
|
||||||
|
list-style-position: inside;
|
||||||
|
}
|
||||||
|
|
||||||
#referenceBook {
|
#referenceBook {
|
||||||
display: none;
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recording-link {
|
||||||
|
font-size: 8pt;
|
||||||
|
color: blue;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fas-trash-alt {
|
||||||
|
color: red;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-backdrop {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
background-color: #000;
|
||||||
|
opacity: 0.5;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-container {
|
||||||
|
position: absolute;
|
||||||
|
width: 300px;
|
||||||
|
/* adjust this to your desired modal width */
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||||
|
z-index: 1001;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
padding: 10px;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-body {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-footer {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
padding: 10px;
|
||||||
|
border-top: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
color: #337ab7;
|
||||||
}/*# sourceMappingURL=style.css.map */
|
}/*# sourceMappingURL=style.css.map */
|
@ -1 +1 @@
|
|||||||
{"version":3,"sources":["style.scss","style.css"],"names":[],"mappings":"AAAA,kCAAA;AACA;EACI,SAAA;ACCJ;;ADEA,6BAAA;AAEA;EACI,aAAA;EACA,mBAAA;EACA,eAAA;EACA,6BAAA;EACA,oBAAA;EACA,yBAAA;EACA,iBAAA;EACA,iCAAA;EACA,cAAA;ACAJ;;ADGA;EACI,WAAA;EACA,4BAAA;ACAJ;;ADGA;EACI,SAAA;EACA,UAAA;ACAJ;;ADGA;EACI,gBAAA;EACA,qBAAA;ACAJ;;ADGA;EACI,kBAAA;ACAJ;;ADGA,GAAA;AACA;EACI,aAAA;EACA,uBAAA;EACA,mBAAA;EACA,YAAA;EACA,WAAA;EACA,kBAAA;EACA,yBAAA;EACA,sBAAA;EACA,YAAA;EACA,kBAAA;EACA,wCAAA;EACA,eAAA;EACA,kBAAA;ACAJ;ADEI;EACI,yBAAA;ACAR;;ADIA;EACI,oCAAA;ACDJ;;ADIA;EACI,UAAA;ACDJ;;ADIA;EACI,mBAAA;EACA,2BAAA;EACA,yBAAA;EACA,kBAAA;EACA,WAAA;EACA,YAAA;EACA,uBAAA;EACA,kBAAA;EACA,wCAAA;ACDJ;;ADIA;EACI,yBAAA;ACDJ;;ADIA;EACI,YAAA;ACDJ;;ADIA;EACI,aAAA;EACA,YAAA;ACDJ;;ADIA;EACI,aAAA;EACA,YAAA;ACDJ;;ADIA;EACI,aAAA;ACDJ;;ADIA;EACI,cAAA;ACDJ;;ADIA;EACI,UAAA;ACDJ;;ADIA;EACI,WAAA;EACA,YAAA;EACA,eAAA;ACDJ;;ADIA;EACI,aAAA;EACA,kBAAA;ACDJ;;ADIA;;EAEI,oCAAA;EACA,uBAAA;ACDJ;;ADIA;EACI,oBAAA;EACA,mBAAA;EACA,UAAA;ACDJ;;ADIA;EACI,oBAAA;EACA,2BAAA;EACA,UAAA;ACDJ;;ADIA;EACI,iBAAA;ACDJ;;ADIA;EACI,aAAA;ACDJ;;ADIA;EACI,SAAA;EACA,UAAA;EACA,qBAAA;EACA,gBAAA;ACDJ;;ADIA;EACI,aAAA;EACA,kBAAA;EACA,YAAA;EACA,oCAAA;EACA,YAAA;EACA,aAAA;ACDJ;;ADIA;EACI,YAAA;EACA,kBAAA;EACA,kBAAA;EACA,eAAA;EACA,gBAAA;EACA,WAAA;EACA,yBAAA;EACA,YAAA;EACA,YAAA;EACA,eAAA;EACA,aAAA;ACDJ;;ADIA;EACI,aAAA;EACA,kBAAA;EACA,YAAA;EACA,sBAAA;EACA,YAAA;EACA,aAAA;EACA,sBAAA;EACA,kBAAA;EACA,wCAAA;EACA,YAAA;EACA,aAAA;EACA,kBAAA;ACDJ;;ADIA;EACI,UAAA;EACA,iBAAA;EACA,eAAA;EACA,iBAAA;EACA,YAAA;ACDJ;;ADIA;EACI,aAAA;ACDJ;;ADIA;EACI,UAAA;ACDJ;;ADIA;;EAEI,YAAA;EACA,qBAAA;ACDJ;;ADIA;EACI,2BAAA;EACA,eAAA;ACDJ;;ADIA;EACI,eAAA;ACDJ;;ADIA;EACI,eAAA;ACDJ;;ADIA;EACI,eAAA;ACDJ;;ADIA;EACI,qBAAA;ACDJ;;ADIA;EACI,eAAA;ACDJ;;ADIA;EACI,aAAA;ACDJ","file":"style.css"}
|
{"version":3,"sources":["style.scss","style.css"],"names":[],"mappings":"AAAA,kCAAA;AACA;EACI,SAAA;ACCJ;;ADEA,6BAAA;AAEA;EACI,aAAA;EACA,mBAAA;EACA,eAAA;EACA,6BAAA;EACA,oBAAA;EACA,yBAAA;EACA,iBAAA;EACA,iCAAA;EACA,cAAA;ACAJ;;ADGA;EACI,WAAA;EACA,4BAAA;ACAJ;;ADGA;EACI,SAAA;EACA,UAAA;ACAJ;;ADGA;EACI,gBAAA;EACA,qBAAA;ACAJ;;ADGA;EACI,kBAAA;ACAJ;;ADGA,GAAA;AACA;EACI,aAAA;EACA,uBAAA;EACA,mBAAA;EACA,YAAA;EACA,WAAA;EACA,kBAAA;EACA,eAAA;EACA,kBAAA;ACAJ;;ADIA;EACI,UAAA;ACDJ;;ADIA;EACI,mBAAA;EACA,2BAAA;EACA,yBAAA;EACA,kBAAA;EACA,WAAA;EACA,YAAA;EACA,uBAAA;EACA,kBAAA;EACA,wCAAA;ACDJ;;ADIA;EACI,wBAAA;ACDJ;;ADIA;EACI,YAAA;ACDJ;;ADIA;EACI,aAAA;EACA,YAAA;ACDJ;;ADIA;EACI,aAAA;EACA,YAAA;ACDJ;;ADIA;EACI,aAAA;ACDJ;;ADIA;EACI,cAAA;ACDJ;;ADIA;EACI,UAAA;ACDJ;;ADIA;EACI,WAAA;EACA,YAAA;EACA,eAAA;ACDJ;;ADIA;EACI,aAAA;EACA,kBAAA;EACA,kBAAA;ACDJ;;ADIA;;EAEI,2BAAA;ACDJ;;ADIA;;;;EAII,oCAAA;EACA,uBAAA;ACDJ;;ADIA;EACI,oBAAA;EACA,mBAAA;EACA,UAAA;ACDJ;;ADIA;EACI,oBAAA;EACA,2BAAA;EACA,UAAA;ACDJ;;ADIA;EACI,iBAAA;ACDJ;;ADIA;EACI,aAAA;EACA,YAAA;EACA,kBAAA;ACDJ;;ADIA;EACI,SAAA;EACA,UAAA;EACA,qBAAA;EACA,gBAAA;ACDJ;;ADIA;EACI,aAAA;EACA,kBAAA;EACA,YAAA;EACA,oCAAA;EACA,YAAA;EACA,aAAA;ACDJ;;ADIA;EACI,YAAA;EACA,kBAAA;EACA,kBAAA;EACA,eAAA;EACA,gBAAA;EACA,WAAA;EACA,yBAAA;EACA,YAAA;EACA,YAAA;EACA,eAAA;EACA,aAAA;ACDJ;;ADIA;EACI,aAAA;EACA,kBAAA;EACA,YAAA;EACA,sBAAA;EACA,YAAA;EACA,aAAA;EACA,sBAAA;EACA,kBAAA;EACA,wCAAA;EACA,YAAA;EACA,aAAA;EACA,kBAAA;ACDJ;;ADIA;EACI,UAAA;EACA,iBAAA;EACA,eAAA;EACA,iBAAA;EACA,YAAA;ACDJ;;ADIA;EACI,aAAA;ACDJ;;ADIA;EACI,UAAA;ACDJ;;ADIA;;EAEI,YAAA;EACA,qBAAA;ACDJ;;ADIA;EACI,2BAAA;EACA,eAAA;ACDJ;;ADIA;EACI,eAAA;ACDJ;;ADIA;EACI,eAAA;ACDJ;;ADIA;EACI,eAAA;ACDJ;;ADIA;EACI,qBAAA;ACDJ;;ADIA;EACI,eAAA;ACDJ;;ADIA;;EAEI,2BAAA;ACDJ;;ADIA;EACI,aAAA;ACDJ;;ADIA;EACI,cAAA;EACA,WAAA;EACA,qBAAA;ACDJ;;ADIA;EACI,UAAA;EACA,eAAA;ACDJ;;ADIA;EACI,eAAA;EACA,MAAA;EACA,QAAA;EACA,SAAA;EACA,OAAA;EACA,sBAAA;EACA,YAAA;EACA,aAAA;ACDJ;;ADIA;EACI,kBAAA;EACA,YAAA;EACA,4CAAA;EACA,cAAA;EACA,aAAA;EACA,sBAAA;EACA,sBAAA;EACA,uCAAA;EACA,aAAA;ACDJ;;ADIA;EACI,yBAAA;EACA,aAAA;EACA,6BAAA;ACDJ;;ADIA;EACI,aAAA;ACDJ;;ADIA;EACI,yBAAA;EACA,aAAA;EACA,0BAAA;ACDJ;;ADIA;EACI,cAAA;ACDJ","file":"style.css"}
|
2
public/css/style.min.css
vendored
2
public/css/style.min.css
vendored
@ -1 +1 @@
|
|||||||
body{margin:0}.inner{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-evenly;align-items:stretch;align-content:flex-start;max-width:1060px;margin:0 auto}.ref-tab{width:60px;padding-top:75px !important}.ref-tab ul{margin:0;padding:0}.ref-tab ul li{list-style:none;list-style-type:none}.tab{margin-bottom:3px}.tab button{display:flex;justify-content:center;align-items:center;height:80px;width:100%;text-align:center;background-color:#f56a6a;color:#fff !important;border:none;border-radius:3px;box-shadow:0 4px 5px rgba(0,0,0,.8);font-size:14px;margin-bottom:3px}.tab button:active{background-color:#7a0016}.activeRef{background-color:#3e8e41 !important}.ref{width:35%}.ref>div#ref{vertical-align:top;justify-content:flex-start;align-content:flex-start;overflow-y:scroll;width:100%;height:100%;border:#000 solid 1px;border-radius:3px;box-shadow:0 2px 5px rgba(0,0,0,.3)}#ref{padding:3px 3px 3px 10px}#passage{width:100px}#newSpeaker{display:none;width:110px}#newSeries{display:none;width:110px}#fields-container{display:none}#fields-container.show{display:block}.notes{width:55%}textarea#notes{width:100%;height:100%;font-size:14pt}#notePreview{display:none;overflow-x:scroll}#previewBtn.active,#show-hide-btn.active{background-color:#f56a6a !important;color:#fff !important}#note-header-left{display:inline-flex;flex-direction:row;width:25%}#note-header-right{display:inline-flex;flex-direction:row-reverse;width:74%}#note-header-left h2.dirty{color:#ff8c00}#note-list{display:none}#note-list ul{margin:0;padding:0;list-style-type:none;list-style:none}div#refQuery{display:none;position:absolute;z-index:100;background-color:rgba(0,0,0,.8);width:400px;height:200px}div#refQuery #referenceSearch{border:none;border-radius:5px;padding:10px 20px;font-size:16px;line-height:1.5;color:#333;background-color:#f4f4f4;width:150px;height:25px;cursor:pointer;display:none}#passage-popup{display:none;position:absolute;z-index:100;background-color:#fff;color:#000;padding:10px;border:1px solid #ccc;border-radius:5px;box-shadow:0 2px 5px rgba(0,0,0,.3);width:300px;height:300px;overflow-x:scroll}#save-check{opacity:0;text-align:right;font-size:20pt;margin-left:15px;color:green}#save-check.saving{color:orange}#save-check.error{color:red}#fields-container input,#fields-container select{width:19.5%;display:inline-block}#old-notes article p:first-child{margin-bottom:0 !important;font-size:10pt}#old-notes article a{font-size:12pt}#old-notes article p:last-child{font-size:12pt}.inner{padding-left:0}.ref h2{display:inline-block}#ref{font-size:12pt}#referenceBook{display:none}/*# sourceMappingURL=style.min.css.map */
|
body{margin:0}.inner{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-evenly;align-items:stretch;align-content:flex-start;max-width:1060px;margin:0 auto}.ref-tab{width:60px;padding-top:55px !important}.ref-tab ul{margin:0;padding:0}.ref-tab ul li{list-style:none;list-style-type:none}.tab{margin-bottom:3px}.tab button{display:flex;justify-content:center;align-items:center;height:80px;width:100%;text-align:center;font-size:14px;margin-bottom:3px}.ref{width:36%}.ref>div#ref{vertical-align:top;justify-content:flex-start;align-content:flex-start;overflow-y:scroll;width:100%;height:100%;border:#000 solid 1px;border-radius:3px;box-shadow:0 2px 5px rgba(0,0,0,.3)}#ref{padding:3px 3px 3px 3px}#passage{width:100px}#newSpeaker{display:none;width:110px}#newSeries{display:none;width:110px}#fields-container{display:none}#fields-container.show{display:block}.notes{width:57%}textarea#notes{width:100%;height:100%;font-size:14pt}#notePreview{display:none;overflow-x:scroll;padding-left:10px}#notePreview ul,#notePreview ol{list-style-position:inside}#previewBtn.active,#show-hide-btn.active,.tab button.active,#openRefBtn.active{background-color:#f56a6a !important;color:#fff !important}#note-header-left{display:inline-flex;flex-direction:row;width:25%}#note-header-right{display:inline-flex;flex-direction:row-reverse;width:74%}#note-header-left h2.dirty{color:#ff8c00}#note-list{display:none;height:100%;overflow-y:scroll}#note-list ul{margin:0;padding:0;list-style-type:none;list-style:none}div#refQuery{display:none;position:absolute;z-index:100;background-color:rgba(0,0,0,.8);width:400px;height:200px}div#refQuery #referenceSearch{border:none;border-radius:5px;padding:10px 20px;font-size:16px;line-height:1.5;color:#333;background-color:#f4f4f4;width:150px;height:25px;cursor:pointer;display:none}#passage-popup{display:none;position:absolute;z-index:100;background-color:#fff;color:#000;padding:10px;border:1px solid #ccc;border-radius:5px;box-shadow:0 2px 5px rgba(0,0,0,.3);width:300px;height:300px;overflow-x:scroll}#save-check{opacity:0;text-align:right;font-size:20pt;margin-left:15px;color:green}#save-check.saving{color:orange}#save-check.error{color:red}#fields-container input,#fields-container select{width:32.5%;display:inline-block}#old-notes article p:first-child{margin-bottom:0 !important;font-size:10pt}#old-notes article a{font-size:12pt}#old-notes article p:last-child{font-size:12pt}.inner{padding-left:0}.ref h2{display:inline-block}#ref{font-size:12pt}#ref ol,#ref ul{list-style-position:inside}#referenceBook{display:none}.recording-link{font-size:8pt;color:blue;text-decoration:none}.fas-trash-alt{color:red;cursor:pointer}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background-color:#000;opacity:.5;z-index:1000}.modal-container{position:absolute;width:300px;margin:0 auto;padding:20px;border:1px solid #ddd;background-color:#fff;box-shadow:0 0 10px rgba(0,0,0,.2);z-index:1001}.modal-header{background-color:#f5f5f5;padding:10px;border-bottom:1px solid #ddd}.modal-body{padding:20px}.modal-footer{background-color:#f5f5f5;padding:10px;border-top:1px solid #ddd}.btn-secondary{color:#337ab7}/*# sourceMappingURL=style.min.css.map */
|
@ -1 +1 @@
|
|||||||
{"version":3,"sources":["style.scss"],"names":[],"mappings":"AACA,KACI,QAAA,CAKJ,OACI,YAAA,CACA,kBAAA,CACA,cAAA,CACA,4BAAA,CACA,mBAAA,CACA,wBAAA,CACA,gBAAA,CAEA,aAAA,CAGJ,SACI,UAAA,CACA,2BAAA,CAGJ,YACI,QAAA,CACA,SAAA,CAGJ,eACI,eAAA,CACA,oBAAA,CAGJ,KACI,iBAAA,CAIJ,YACI,YAAA,CACA,sBAAA,CACA,kBAAA,CACA,WAAA,CACA,UAAA,CACA,iBAAA,CACA,wBAAA,CACA,qBAAA,CACA,WAAA,CACA,iBAAA,CACA,mCAAA,CACA,cAAA,CACA,iBAAA,CAEA,mBACI,wBAAA,CAIR,WACI,mCAAA,CAGJ,KACI,SAAA,CAGJ,aACI,kBAAA,CACA,0BAAA,CACA,wBAAA,CACA,iBAAA,CACA,UAAA,CACA,WAAA,CACA,qBAAA,CACA,iBAAA,CACA,mCAAA,CAGJ,KACI,wBAAA,CAGJ,SACI,WAAA,CAGJ,YACI,YAAA,CACA,WAAA,CAGJ,WACI,YAAA,CACA,WAAA,CAGJ,kBACI,YAAA,CAGJ,uBACI,aAAA,CAGJ,OACI,SAAA,CAGJ,eACI,UAAA,CACA,WAAA,CACA,cAAA,CAGJ,aACI,YAAA,CACA,iBAAA,CAGJ,yCAEI,mCAAA,CACA,qBAAA,CAGJ,kBACI,mBAAA,CACA,kBAAA,CACA,SAAA,CAGJ,mBACI,mBAAA,CACA,0BAAA,CACA,SAAA,CAGJ,2BACI,aAAA,CAGJ,WACI,YAAA,CAGJ,cACI,QAAA,CACA,SAAA,CACA,oBAAA,CACA,eAAA,CAGJ,aACI,YAAA,CACA,iBAAA,CACA,WAAA,CACA,+BAAA,CACA,WAAA,CACA,YAAA,CAGJ,8BACI,WAAA,CACA,iBAAA,CACA,iBAAA,CACA,cAAA,CACA,eAAA,CACA,UAAA,CACA,wBAAA,CACA,WAAA,CACA,WAAA,CACA,cAAA,CACA,YAAA,CAGJ,eACI,YAAA,CACA,iBAAA,CACA,WAAA,CACA,qBAAA,CACA,UAAA,CACA,YAAA,CACA,qBAAA,CACA,iBAAA,CACA,mCAAA,CACA,WAAA,CACA,YAAA,CACA,iBAAA,CAGJ,YACI,SAAA,CACA,gBAAA,CACA,cAAA,CACA,gBAAA,CACA,WAAA,CAGJ,mBACI,YAAA,CAGJ,kBACI,SAAA,CAGJ,iDAEI,WAAA,CACA,oBAAA,CAGJ,iCACI,0BAAA,CACA,cAAA,CAGJ,qBACI,cAAA,CAGJ,gCACI,cAAA,CAGJ,OACI,cAAA,CAGJ,QACI,oBAAA,CAGJ,KACI,cAAA,CAGJ,eACI,YAAA","file":"style.min.css"}
|
{"version":3,"sources":["style.scss"],"names":[],"mappings":"AACA,KACI,QAAA,CAKJ,OACI,YAAA,CACA,kBAAA,CACA,cAAA,CACA,4BAAA,CACA,mBAAA,CACA,wBAAA,CACA,gBAAA,CAEA,aAAA,CAGJ,SACI,UAAA,CACA,2BAAA,CAGJ,YACI,QAAA,CACA,SAAA,CAGJ,eACI,eAAA,CACA,oBAAA,CAGJ,KACI,iBAAA,CAIJ,YACI,YAAA,CACA,sBAAA,CACA,kBAAA,CACA,WAAA,CACA,UAAA,CACA,iBAAA,CACA,cAAA,CACA,iBAAA,CAIJ,KACI,SAAA,CAGJ,aACI,kBAAA,CACA,0BAAA,CACA,wBAAA,CACA,iBAAA,CACA,UAAA,CACA,WAAA,CACA,qBAAA,CACA,iBAAA,CACA,mCAAA,CAGJ,KACI,uBAAA,CAGJ,SACI,WAAA,CAGJ,YACI,YAAA,CACA,WAAA,CAGJ,WACI,YAAA,CACA,WAAA,CAGJ,kBACI,YAAA,CAGJ,uBACI,aAAA,CAGJ,OACI,SAAA,CAGJ,eACI,UAAA,CACA,WAAA,CACA,cAAA,CAGJ,aACI,YAAA,CACA,iBAAA,CACA,iBAAA,CAGJ,gCAEI,0BAAA,CAGJ,+EAII,mCAAA,CACA,qBAAA,CAGJ,kBACI,mBAAA,CACA,kBAAA,CACA,SAAA,CAGJ,mBACI,mBAAA,CACA,0BAAA,CACA,SAAA,CAGJ,2BACI,aAAA,CAGJ,WACI,YAAA,CACA,WAAA,CACA,iBAAA,CAGJ,cACI,QAAA,CACA,SAAA,CACA,oBAAA,CACA,eAAA,CAGJ,aACI,YAAA,CACA,iBAAA,CACA,WAAA,CACA,+BAAA,CACA,WAAA,CACA,YAAA,CAGJ,8BACI,WAAA,CACA,iBAAA,CACA,iBAAA,CACA,cAAA,CACA,eAAA,CACA,UAAA,CACA,wBAAA,CACA,WAAA,CACA,WAAA,CACA,cAAA,CACA,YAAA,CAGJ,eACI,YAAA,CACA,iBAAA,CACA,WAAA,CACA,qBAAA,CACA,UAAA,CACA,YAAA,CACA,qBAAA,CACA,iBAAA,CACA,mCAAA,CACA,WAAA,CACA,YAAA,CACA,iBAAA,CAGJ,YACI,SAAA,CACA,gBAAA,CACA,cAAA,CACA,gBAAA,CACA,WAAA,CAGJ,mBACI,YAAA,CAGJ,kBACI,SAAA,CAGJ,iDAEI,WAAA,CACA,oBAAA,CAGJ,iCACI,0BAAA,CACA,cAAA,CAGJ,qBACI,cAAA,CAGJ,gCACI,cAAA,CAGJ,OACI,cAAA,CAGJ,QACI,oBAAA,CAGJ,KACI,cAAA,CAGJ,gBAEI,0BAAA,CAGJ,eACI,YAAA,CAGJ,gBACI,aAAA,CACA,UAAA,CACA,oBAAA,CAGJ,eACI,SAAA,CACA,cAAA,CAGJ,gBACI,cAAA,CACA,KAAA,CACA,OAAA,CACA,QAAA,CACA,MAAA,CACA,qBAAA,CACA,UAAA,CACA,YAAA,CAGJ,iBACI,iBAAA,CACA,WAAA,CAEA,aAAA,CACA,YAAA,CACA,qBAAA,CACA,qBAAA,CACA,kCAAA,CACA,YAAA,CAGJ,cACI,wBAAA,CACA,YAAA,CACA,4BAAA,CAGJ,YACI,YAAA,CAGJ,cACI,wBAAA,CACA,YAAA,CACA,yBAAA,CAGJ,eACI,aAAA","file":"style.min.css"}
|
@ -19,7 +19,7 @@ body {
|
|||||||
|
|
||||||
.ref-tab {
|
.ref-tab {
|
||||||
width: 60px;
|
width: 60px;
|
||||||
padding-top: 75px !important;
|
padding-top: 55px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ref-tab ul {
|
.ref-tab ul {
|
||||||
@ -44,25 +44,13 @@ body {
|
|||||||
height: 80px;
|
height: 80px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: #f56a6a;
|
|
||||||
color: #fff !important;
|
|
||||||
border: none;
|
|
||||||
border-radius: 3px;
|
|
||||||
box-shadow: 0 4px 5px rgba(0, 0, 0, 0.8);
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
margin-bottom: 3px;
|
margin-bottom: 3px;
|
||||||
|
|
||||||
&:active {
|
|
||||||
background-color: #7a0016;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.activeRef {
|
|
||||||
background-color: #3e8e41 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ref {
|
.ref {
|
||||||
width: 35%;
|
width: 36%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ref>div#ref {
|
.ref>div#ref {
|
||||||
@ -78,7 +66,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ref {
|
#ref {
|
||||||
padding: 3px 3px 3px 10px;
|
padding: 3px 3px 3px 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#passage {
|
#passage {
|
||||||
@ -104,7 +92,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.notes {
|
.notes {
|
||||||
width: 55%
|
width: 57%
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea#notes {
|
textarea#notes {
|
||||||
@ -116,10 +104,18 @@ textarea#notes {
|
|||||||
#notePreview {
|
#notePreview {
|
||||||
display: none;
|
display: none;
|
||||||
overflow-x: scroll;
|
overflow-x: scroll;
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#notePreview ul,
|
||||||
|
#notePreview ol {
|
||||||
|
list-style-position: inside;
|
||||||
}
|
}
|
||||||
|
|
||||||
#previewBtn.active,
|
#previewBtn.active,
|
||||||
#show-hide-btn.active {
|
#show-hide-btn.active,
|
||||||
|
.tab button.active,
|
||||||
|
#openRefBtn.active {
|
||||||
background-color: #f56a6a !important;
|
background-color: #f56a6a !important;
|
||||||
color: white !important;
|
color: white !important;
|
||||||
}
|
}
|
||||||
@ -142,6 +138,8 @@ textarea#notes {
|
|||||||
|
|
||||||
#note-list {
|
#note-list {
|
||||||
display: none;
|
display: none;
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
#note-list ul {
|
#note-list ul {
|
||||||
@ -207,7 +205,7 @@ div#refQuery #referenceSearch {
|
|||||||
|
|
||||||
#fields-container input,
|
#fields-container input,
|
||||||
#fields-container select {
|
#fields-container select {
|
||||||
width: 19.5%;
|
width: 32.5%;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,6 +234,65 @@ div#refQuery #referenceSearch {
|
|||||||
font-size: 12pt;
|
font-size: 12pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ref ol,
|
||||||
|
#ref ul {
|
||||||
|
list-style-position: inside;
|
||||||
|
}
|
||||||
|
|
||||||
#referenceBook {
|
#referenceBook {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.recording-link {
|
||||||
|
font-size: 8pt;
|
||||||
|
color: blue;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fas-trash-alt {
|
||||||
|
color: red;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-backdrop {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
background-color: #000;
|
||||||
|
opacity: 0.5;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-container {
|
||||||
|
position: absolute;
|
||||||
|
width: 300px;
|
||||||
|
/* adjust this to your desired modal width */
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||||
|
z-index: 1001;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
padding: 10px;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-body {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-footer {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
padding: 10px;
|
||||||
|
border-top: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
color: #337ab7;
|
||||||
|
}
|
@ -1354,5 +1354,29 @@
|
|||||||
"wlc": [
|
"wlc": [
|
||||||
1,
|
1,
|
||||||
196
|
196
|
||||||
|
],
|
||||||
|
"lbc": [
|
||||||
|
1,
|
||||||
|
32
|
||||||
|
],
|
||||||
|
"39a": [
|
||||||
|
1,
|
||||||
|
39
|
||||||
|
],
|
||||||
|
"1hc": [
|
||||||
|
1,
|
||||||
|
10
|
||||||
|
],
|
||||||
|
"2hc": [
|
||||||
|
1,
|
||||||
|
30
|
||||||
|
],
|
||||||
|
"sd": [
|
||||||
|
1,
|
||||||
|
32
|
||||||
|
],
|
||||||
|
"agc": [
|
||||||
|
1,
|
||||||
|
28
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -4,40 +4,83 @@ var references = {};
|
|||||||
var tabs = [];
|
var tabs = [];
|
||||||
let saved = false;
|
let saved = false;
|
||||||
let textDirty = false;
|
let textDirty = false;
|
||||||
let saveTimeout = 10000;
|
|
||||||
var to = null;
|
var to = null;
|
||||||
let controller;
|
let controller;
|
||||||
var BOOKS = {};
|
var BOOKS = {};
|
||||||
|
|
||||||
fetch('/js/data.json')
|
$(function () {
|
||||||
.then((res) => {
|
setHeight();
|
||||||
if (!res.ok) {
|
setBooks();
|
||||||
throw new Error('HTTP Error: Status: ${res.status}');
|
setEventListeners();
|
||||||
|
$('#note-table').DataTable({
|
||||||
|
paging: false,
|
||||||
|
ajax: {
|
||||||
|
url: '/index.php/get-notes',
|
||||||
|
type: 'POST'
|
||||||
|
},
|
||||||
|
columns: [
|
||||||
|
{ data: 'link' },
|
||||||
|
{ data: 'speaker.name' },
|
||||||
|
{ data: 'passage' },
|
||||||
|
{
|
||||||
|
data: 'date.date',
|
||||||
|
render: DataTable.render.date("L")
|
||||||
|
},
|
||||||
|
]
|
||||||
|
});
|
||||||
|
$('#shareBtn').on('click', openShareNote);
|
||||||
|
$('#modal-backdrop').on('click', closeShareNote);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches data from '/js/data.json', assigns it to BOOKS, and handles errors.
|
||||||
|
*
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
function setBooks() {
|
||||||
|
fetch('/js/data.json')
|
||||||
|
.then((res) => {
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error('HTTP Error: Status: ${res.status}');
|
||||||
|
}
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
BOOKS = data;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.log(error);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets event listeners for keyup events on the document and the '#notes' element.
|
||||||
|
*
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
function setEventListeners() {
|
||||||
|
document.addEventListener('keyup', function (event) {
|
||||||
|
if (event.key == "F3") {
|
||||||
|
openRef(false);
|
||||||
}
|
}
|
||||||
return res.json();
|
});
|
||||||
})
|
|
||||||
.then((data) => {
|
|
||||||
BOOKS = data;
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.log(error);
|
|
||||||
})
|
|
||||||
|
|
||||||
document.addEventListener('keyup', function (event) {
|
document.querySelector('#notes').addEventListener('keyup', function (event) {
|
||||||
if (event.key == "F3") {
|
let key = event.keyCode;
|
||||||
openRef(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.querySelector('#notes').addEventListener('keyup', function (event) {
|
if (key >= 48 && key <= 90 || key >= 96 && key <= 111 || key >= 186 && key <= 222) {
|
||||||
let key = event.keyCode;
|
textDirty = true;
|
||||||
|
document.querySelector('#note-header-left h2').classList.add('dirty');
|
||||||
if (key >= 48 && key <= 90 || key >= 96 && key <= 111 || key >= 186 && key <= 222) {
|
}
|
||||||
textDirty = true;
|
});
|
||||||
document.querySelector('#note-header-left h2').classList.add('dirty');
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the height of various elements on the page based on the window's inner height.
|
||||||
|
* Also initializes a datepicker and event listener for the search input field.
|
||||||
|
*
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
function setHeight() {
|
function setHeight() {
|
||||||
md = new markdownit({
|
md = new markdownit({
|
||||||
html: true,
|
html: true,
|
||||||
@ -78,10 +121,17 @@ function setHeight() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (!to) {
|
if (!to) {
|
||||||
to = setTimeout(saveNote, saveTimeout);
|
to = setTimeout(saveNote, saveInterval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for notes based on the query entered in the search field.
|
||||||
|
* Sends a POST request to the '/index.php/search' endpoint with the query as a JSON payload.
|
||||||
|
* Updates the '#old-notes' element with the search results.
|
||||||
|
*
|
||||||
|
* @return {Promise} A Promise that resolves with the search results.
|
||||||
|
*/
|
||||||
function search() {
|
function search() {
|
||||||
query = document.querySelector('#query').value;
|
query = document.querySelector('#query').value;
|
||||||
fetch('/index.php/search', {
|
fetch('/index.php/search', {
|
||||||
@ -115,6 +165,15 @@ function search() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the state of the note editor by clearing the text and form fields,
|
||||||
|
* resetting the references, and removing any dirty classes. It also sets the
|
||||||
|
* date to the current date, clears the speaker, series, template, passage,
|
||||||
|
* recording, and note ID fields. Finally, it clears the reference list and
|
||||||
|
* reference display.
|
||||||
|
*
|
||||||
|
* @return {void} This function does not return anything.
|
||||||
|
*/
|
||||||
function newNote() {
|
function newNote() {
|
||||||
notes = document.querySelector('#notes');
|
notes = document.querySelector('#notes');
|
||||||
notes.text = '';
|
notes.text = '';
|
||||||
@ -133,7 +192,8 @@ function newNote() {
|
|||||||
document.querySelector('#series').value = 0;
|
document.querySelector('#series').value = 0;
|
||||||
document.querySelector('#template').value = 0;
|
document.querySelector('#template').value = 0;
|
||||||
document.querySelector('#passage').value = '';
|
document.querySelector('#passage').value = '';
|
||||||
document.querySelector('#noteId').value = uuidv4();
|
document.querySelector('#recording').value = '';
|
||||||
|
document.querySelector('#noteId').value = '';
|
||||||
|
|
||||||
document.querySelector('#ref-list').innerHTML = '';
|
document.querySelector('#ref-list').innerHTML = '';
|
||||||
document.querySelector('#ref').innerHTML = '';
|
document.querySelector('#ref').innerHTML = '';
|
||||||
@ -153,11 +213,12 @@ function saveNote(event) {
|
|||||||
|
|
||||||
if (!textDirty || !validateNote()) {
|
if (!textDirty || !validateNote()) {
|
||||||
clearTimeout(to);
|
clearTimeout(to);
|
||||||
to = setTimeout(saveNote, saveTimeout);
|
to = setTimeout(saveNote, saveInterval);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let saveCheck = document.querySelector('#save-check');
|
let saveCheck = document.querySelector('#save-check');
|
||||||
|
var noteText = document.querySelector('#notes').value;
|
||||||
|
|
||||||
startSave();
|
startSave();
|
||||||
|
|
||||||
@ -169,6 +230,7 @@ function saveNote(event) {
|
|||||||
series: document.querySelector('#series').value,
|
series: document.querySelector('#series').value,
|
||||||
passage: document.querySelector('#passage').value,
|
passage: document.querySelector('#passage').value,
|
||||||
note: document.querySelector('#notes').value,
|
note: document.querySelector('#notes').value,
|
||||||
|
recording: document.querySelector('#recording').value,
|
||||||
refs: references
|
refs: references
|
||||||
};
|
};
|
||||||
$.ajax({
|
$.ajax({
|
||||||
@ -177,36 +239,49 @@ function saveNote(event) {
|
|||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
data: JSON.stringify(note),
|
data: JSON.stringify(note),
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
timeout: 5000
|
timeout: saveTimeout
|
||||||
})
|
})
|
||||||
.done(function (data) {
|
.done(function (data) {
|
||||||
if (data.msg == 'saved' && !saved) {
|
if (data.msg == 'saved' && !saved) {
|
||||||
saveCheck.classList.remove('saving');
|
saveFailureCount = SAVE_FAILURE_LIMIT;
|
||||||
|
saveCheck.classList.remove('saving', 'error', 'fa-times-circle', 'fa-save');
|
||||||
showSave();
|
showSave();
|
||||||
saved = true;
|
if (noteText == document.querySelector('#notes').value) {
|
||||||
textDirty = false;
|
saved = true;
|
||||||
document.querySelector('#note-header-left h2').classList.remove('dirty');
|
textDirty = false;
|
||||||
|
document.querySelector('#note-header-left h2').classList.remove('dirty');
|
||||||
|
}
|
||||||
|
|
||||||
if (data.new) {
|
if (data.new) {
|
||||||
document.querySelector('#noteId').value = data.id;
|
document.querySelector('#noteId').value = data.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.fail(function (data) {
|
.fail(function (xhr, status, error) {
|
||||||
saveCheck.classList.remove('saving');
|
saveFailureCount--;
|
||||||
saveCheck.classList.add('error');
|
saveCheck.classList.remove('saving', 'fa-save');
|
||||||
console.error(data);
|
saveCheck.classList.add('fa-times-circle', 'error');
|
||||||
|
console.error(error);
|
||||||
})
|
})
|
||||||
.always(function (xhr, status) {
|
.always(function (xhr, status) {
|
||||||
if (status == 'timeout') {
|
if (status == 'timeout') {
|
||||||
saveCheck.classList.remove('saving');
|
saveCheck.classList.remove('saving', 'fa-save');
|
||||||
saveCheck.classList.add('error');
|
saveCheck.classList.add('error', 'fa-times-circle');
|
||||||
}
|
}
|
||||||
clearTimeout(to);
|
clearTimeout(to);
|
||||||
to = setTimeout(saveNote, saveTimeout);
|
if (saveFailureCount > 0) {
|
||||||
|
to = setTimeout(saveNote, saveInterval);
|
||||||
|
} else {
|
||||||
|
saveFailureCount = SAVE_FAILURE_LIMIT;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates a note by checking if all required fields are filled.
|
||||||
|
*
|
||||||
|
* @return {boolean} Returns true if all required fields are filled, false otherwise.
|
||||||
|
*/
|
||||||
function validateNote() {
|
function validateNote() {
|
||||||
const note = document.querySelector('#notes');
|
const note = document.querySelector('#notes');
|
||||||
const date = document.querySelector('#noteDate');
|
const date = document.querySelector('#noteDate');
|
||||||
@ -225,13 +300,26 @@ function validateNote() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a given UUID is valid.
|
||||||
|
*
|
||||||
|
* @param {string} uuid - The UUID to be validated.
|
||||||
|
* @return {boolean} Returns true if the UUID is valid, false otherwise.
|
||||||
|
*/
|
||||||
function isUuidValid(uuid) {
|
function isUuidValid(uuid) {
|
||||||
const regex = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[8|9|a|b][a-f0-9]{3}-[a-f0-9]{12}$/i;
|
const regex = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[8|9|a|b][a-f0-9]{3}-[a-f0-9]{12}$/i;
|
||||||
return regex.test(uuid);
|
return regex.test(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the save process by updating the save-check element's classList, removing error, fa-times-circle, and fa-save classes,
|
||||||
|
* adding the 'saving' and 'fa-save' classes, and setting the opacity to 1.
|
||||||
|
*
|
||||||
|
* @return {void} This function does not return anything.
|
||||||
|
*/
|
||||||
function startSave() {
|
function startSave() {
|
||||||
document.querySelector('#save-check').classList.add('saving');
|
document.querySelector('#save-check').classList.remove('error', 'fa-times-circle', 'fa-save');
|
||||||
|
document.querySelector('#save-check').classList.add('saving', 'fa-save');
|
||||||
document.querySelector('#save-check').style.opacity = 1;
|
document.querySelector('#save-check').style.opacity = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,6 +333,7 @@ function showSave() {
|
|||||||
if (saved) { return; }
|
if (saved) { return; }
|
||||||
|
|
||||||
var checkmark = document.getElementById("save-check");
|
var checkmark = document.getElementById("save-check");
|
||||||
|
checkmark.classList.add('fa-save');
|
||||||
|
|
||||||
// Schedule the animation to run every 1 second (which is equivalent to a 1-second delay between each iteration)
|
// Schedule the animation to run every 1 second (which is equivalent to a 1-second delay between each iteration)
|
||||||
var si = setInterval(function () {
|
var si = setInterval(function () {
|
||||||
@ -264,33 +353,44 @@ function showSave() {
|
|||||||
/**
|
/**
|
||||||
* Function to discard the note by clearing all input fields and closing the menu.
|
* Function to discard the note by clearing all input fields and closing the menu.
|
||||||
*/
|
*/
|
||||||
function discardNote() {
|
function deleteNote(noteId, link) {
|
||||||
document.querySelector('#noteTitle').value = '';
|
document.querySelector('#noteTitle').value = '';
|
||||||
document.querySelector('#speaker').value = 0;
|
document.querySelector('#speaker').value = 0;
|
||||||
document.querySelector('#series').value = 0;
|
document.querySelector('#series').value = 0;
|
||||||
document.querySelector('#template').value = 0;
|
document.querySelector('#template').value = 0;
|
||||||
document.querySelector('#passage').value = '';
|
document.querySelector('#passage').value = '';
|
||||||
document.querySelector('#notes').value = '';
|
document.querySelector('#notes').value = '';
|
||||||
|
document.querySelector('#recording').value = '';
|
||||||
|
document.querySelector('#noteDate').value = '';
|
||||||
|
document.querySelector('#noteId').value = '';
|
||||||
|
|
||||||
fetch('/index.php/discard-note', {
|
var row = link.parentElement.parentElement;
|
||||||
|
|
||||||
|
fetch('/index.php/delete-note', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
'id': document.querySelector('#noteId').value
|
'id': noteId
|
||||||
})
|
})
|
||||||
.then(response => response.json())
|
})
|
||||||
.then(data => {
|
.then(response => response.json())
|
||||||
if (data.msg == 'deleted') {
|
.then(data => {
|
||||||
alert('Note deleted.');
|
if (data.msg != 'deleted') {
|
||||||
}
|
return;
|
||||||
})
|
}
|
||||||
});
|
|
||||||
|
|
||||||
openRef();
|
alert('Note deleted.');
|
||||||
|
row.remove();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles the display of the new speaker input field and hides the speaker select field.
|
||||||
|
*
|
||||||
|
* @return {void} This function does not return anything.
|
||||||
|
*/
|
||||||
function newSpeaker() {
|
function newSpeaker() {
|
||||||
if (document.querySelector('#speaker').value == 'new') {
|
if (document.querySelector('#speaker').value == 'new') {
|
||||||
document.querySelector('#newSpeaker').style.display = 'inline-block';
|
document.querySelector('#newSpeaker').style.display = 'inline-block';
|
||||||
@ -301,6 +401,12 @@ function newSpeaker() {
|
|||||||
textDirty = true;
|
textDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a new speaker to the database and updates the UI with the new speaker option.
|
||||||
|
*
|
||||||
|
* @param {Event} event - The keydown event triggered by the user.
|
||||||
|
* @return {Promise} A Promise that resolves with the results of the fetch request.
|
||||||
|
*/
|
||||||
function saveSpeaker(event) {
|
function saveSpeaker(event) {
|
||||||
if (event.keyCode == 13) {
|
if (event.keyCode == 13) {
|
||||||
fetch('/index.php/save-speaker', {
|
fetch('/index.php/save-speaker', {
|
||||||
@ -329,6 +435,10 @@ function saveSpeaker(event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A description of the entire function.
|
||||||
|
*
|
||||||
|
*/
|
||||||
function newSeries() {
|
function newSeries() {
|
||||||
if (document.querySelector('#series').value == 'new') {
|
if (document.querySelector('#series').value == 'new') {
|
||||||
document.querySelector('#newSeries').style.display = 'inline-block';
|
document.querySelector('#newSeries').style.display = 'inline-block';
|
||||||
@ -339,6 +449,12 @@ function newSeries() {
|
|||||||
textDirty = true;
|
textDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a series by making a POST request to '/index.php/save-series' with the series name as the request body.
|
||||||
|
*
|
||||||
|
* @param {Event} event - The keydown event.
|
||||||
|
* @return {Promise} A Promise that resolves with the response from the server.
|
||||||
|
*/
|
||||||
function saveSeries(event) {
|
function saveSeries(event) {
|
||||||
if (event.keyCode == 13) {
|
if (event.keyCode == 13) {
|
||||||
fetch('/index.php/save-series', {
|
fetch('/index.php/save-series', {
|
||||||
@ -367,7 +483,14 @@ function saveSeries(event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the reference with the option to close the sidebar.
|
||||||
|
*
|
||||||
|
* @param {boolean} closeSidebar - Indicates whether to close the sidebar when opening the reference.
|
||||||
|
*/
|
||||||
function openRef(closeSidebar = true) {
|
function openRef(closeSidebar = true) {
|
||||||
|
document.querySelector('#openRefBtn').classList.add('active');
|
||||||
|
|
||||||
refQuery = document.querySelector('#refQuery');
|
refQuery = document.querySelector('#refQuery');
|
||||||
refQuery.style.display = 'block';
|
refQuery.style.display = 'block';
|
||||||
|
|
||||||
@ -379,6 +502,11 @@ function openRef(closeSidebar = true) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the reference query and resets the reference search form.
|
||||||
|
*
|
||||||
|
* @return {void} This function does not return anything.
|
||||||
|
*/
|
||||||
function closeRef() {
|
function closeRef() {
|
||||||
document.querySelector('#referenceSearch').value = '';
|
document.querySelector('#referenceSearch').value = '';
|
||||||
document.querySelector('#referenceSearch').style.display = '';
|
document.querySelector('#referenceSearch').style.display = '';
|
||||||
@ -389,8 +517,17 @@ function closeRef() {
|
|||||||
document.querySelector('#verse-range').innerText = '';
|
document.querySelector('#verse-range').innerText = '';
|
||||||
|
|
||||||
document.querySelector('#refQuery').style.display = 'none';
|
document.querySelector('#refQuery').style.display = 'none';
|
||||||
|
document.querySelector('#openRefBtn').classList.remove('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a reference based on the provided type, book, and input.
|
||||||
|
*
|
||||||
|
* @param {string} type - The type of reference.
|
||||||
|
* @param {string} book - The book of the reference.
|
||||||
|
* @param {string} input - The input for the reference.
|
||||||
|
* @return {void} This function does not return anything directly, but processes the fetched reference data.
|
||||||
|
*/
|
||||||
function queryRef(type = null, book = null, input = null) {
|
function queryRef(type = null, book = null, input = null) {
|
||||||
if (!input) {
|
if (!input) {
|
||||||
var input = document.querySelector('#refQuery #referenceSearch').value;
|
var input = document.querySelector('#refQuery #referenceSearch').value;
|
||||||
@ -435,13 +572,20 @@ function queryRef(type = null, book = null, input = null) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A function to create a button element with the specified title and event listeners for click and double click actions.
|
||||||
|
*
|
||||||
|
* @param {string} title - The title to be displayed on the button.
|
||||||
|
* @return {Element} The created button element.
|
||||||
|
*/
|
||||||
function makeButton(title) {
|
function makeButton(title) {
|
||||||
var btn = document.createElement('button');
|
var btn = document.createElement('button');
|
||||||
btn.innerText = title;
|
btn.innerText = title;
|
||||||
|
btn.class = 'button';
|
||||||
btn.addEventListener('click', function () {
|
btn.addEventListener('click', function () {
|
||||||
removeActiveRef();
|
removeActiveRef();
|
||||||
document.querySelector('#ref').innerHTML = md.render(references[title]);
|
document.querySelector('#ref').innerHTML = md.render(references[title]);
|
||||||
this.classList.add('activeRef');
|
this.classList.add('active');
|
||||||
findRefLinks();
|
findRefLinks();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -456,20 +600,32 @@ function makeButton(title) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
removeActiveRef();
|
removeActiveRef();
|
||||||
btn.classList.add('activeRef');
|
btn.classList.add('active');
|
||||||
|
|
||||||
return btn;
|
return btn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the 'active' class from all elements with the class 'active'.
|
||||||
|
*
|
||||||
|
* @return {void} This function does not return a value.
|
||||||
|
*/
|
||||||
function removeActiveRef() {
|
function removeActiveRef() {
|
||||||
tabs = document.querySelectorAll('.activeRef');
|
tabs = document.querySelectorAll('.active');
|
||||||
for (var t in tabs) {
|
for (var t in tabs) {
|
||||||
if (isFinite(parseInt(t))) {
|
if (isFinite(parseInt(t))) {
|
||||||
tabs[t].classList.remove('activeRef');
|
tabs[t].classList.remove('active');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a template from the server and sets it as the value of a specified destination element.
|
||||||
|
*
|
||||||
|
* @param {string} orig - The ID of the element containing the original template value.
|
||||||
|
* @param {string} dest - The ID of the destination element where the retrieved template will be set.
|
||||||
|
* @return {Promise} A Promise that resolves when the template is successfully retrieved and set as the value of the destination element.
|
||||||
|
*/
|
||||||
function retrieveTemplate(orig, dest) {
|
function retrieveTemplate(orig, dest) {
|
||||||
const temp = document.querySelector('#' + orig);
|
const temp = document.querySelector('#' + orig);
|
||||||
if (temp.value == '0') {
|
if (temp.value == '0') {
|
||||||
@ -513,6 +669,11 @@ function saveTemplate() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles the visibility of the fields container and updates the active state of the show/hide button.
|
||||||
|
*
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
function toggleFields() {
|
function toggleFields() {
|
||||||
const fieldsContainer = document.getElementById('fields-container');
|
const fieldsContainer = document.getElementById('fields-container');
|
||||||
const showHideBtn = document.getElementById('show-hide-btn');
|
const showHideBtn = document.getElementById('show-hide-btn');
|
||||||
@ -530,6 +691,11 @@ function toggleFields() {
|
|||||||
setHeight();
|
setHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of books based on the selected reference type.
|
||||||
|
*
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
function retrieveBooks() {
|
function retrieveBooks() {
|
||||||
document.querySelector('#chapter-range').innerText = '';
|
document.querySelector('#chapter-range').innerText = '';
|
||||||
document.querySelector('#verse-range').innerText = '';
|
document.querySelector('#verse-range').innerText = '';
|
||||||
@ -573,6 +739,30 @@ function retrieveBooks() {
|
|||||||
newBook.text = BOOKS.cd[x];
|
newBook.text = BOOKS.cd[x];
|
||||||
bookList.appendChild(newBook);
|
bookList.appendChild(newBook);
|
||||||
}
|
}
|
||||||
|
} else if (selectedType == 'note') {
|
||||||
|
var none = document.createElement("option");
|
||||||
|
none.value = '';
|
||||||
|
none.text = '-- Select --';
|
||||||
|
bookList.appendChild(none);
|
||||||
|
|
||||||
|
fetch('/index.php/retrieve-reference', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
'type': 'note'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(results => {
|
||||||
|
for (var x in results) {
|
||||||
|
var newBook = document.createElement("option");
|
||||||
|
newBook.value = results[x].id;
|
||||||
|
newBook.text = results[x].title;
|
||||||
|
bookList.appendChild(newBook);
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
var min = BOOKS[selectedType][0];
|
var min = BOOKS[selectedType][0];
|
||||||
var max = BOOKS[selectedType][1];
|
var max = BOOKS[selectedType][1];
|
||||||
@ -589,6 +779,11 @@ function retrieveBooks() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the books based on the selected reference type and updates the chapter range.
|
||||||
|
*
|
||||||
|
* @return {void} This function does not return anything.
|
||||||
|
*/
|
||||||
function filterBooks() {
|
function filterBooks() {
|
||||||
document.querySelector('#chapter-range').innerText = '';
|
document.querySelector('#chapter-range').innerText = '';
|
||||||
document.querySelector('#verse-range').innerText = '';
|
document.querySelector('#verse-range').innerText = '';
|
||||||
@ -604,6 +799,11 @@ function filterBooks() {
|
|||||||
chapterRange.innerText = 'Chapters: ' + max;
|
chapterRange.innerText = 'Chapters: ' + max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the verse based on the selected book and chapter.
|
||||||
|
*
|
||||||
|
* @return {void} This function does not return anything.
|
||||||
|
*/
|
||||||
function filterVerse() {
|
function filterVerse() {
|
||||||
if (document.querySelector('#referenceType').value != 'bible') {
|
if (document.querySelector('#referenceType').value != 'bible') {
|
||||||
return;
|
return;
|
||||||
@ -622,15 +822,54 @@ function filterVerse() {
|
|||||||
verseRange.innerText = 'Verse: ' + verse;
|
verseRange.innerText = 'Verse: ' + verse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the reference type from the server and populates the reference series dropdown.
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} el - The element that triggered the function.
|
||||||
|
* @return {Promise} A promise that resolves with the response from the server.
|
||||||
|
*/
|
||||||
|
function retrieveReferenceType(el) {
|
||||||
|
fetch('/index.php/reference/' + el.value, {
|
||||||
|
method: 'GET',
|
||||||
|
header: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(results => {
|
||||||
|
document.querySelector('#referenceSeries').innerHTML = '';
|
||||||
|
var none = document.createElement('option');
|
||||||
|
none.value = '';
|
||||||
|
none.text = '-- Select --';
|
||||||
|
document.querySelector('#referenceSeries').appendChild(none);
|
||||||
|
|
||||||
|
for (var x in results) {
|
||||||
|
var newSeries = document.createElement('option');
|
||||||
|
newSeries.value = results[x].id;
|
||||||
|
newSeries.text = results[x].label;
|
||||||
|
document.querySelector('#referenceSeries').appendChild(newSeries);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a reference based on the provided element value.
|
||||||
|
*
|
||||||
|
* @param {Element} el - The element triggering the reference retrieval
|
||||||
|
* @return {void} No return value
|
||||||
|
*/
|
||||||
function retrieveReference(el) {
|
function retrieveReference(el) {
|
||||||
|
if (el.value == 'new') {
|
||||||
|
document.querySelector('#refName').style.display = 'inline-block';
|
||||||
|
return;
|
||||||
|
}
|
||||||
fetch('/index.php/get-reference', {
|
fetch('/index.php/get-reference', {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
header: {
|
header: {
|
||||||
"Content-Type": "application/json"
|
"Content-Type": "application/json"
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
file: el.value,
|
id: el.value
|
||||||
type: el.options[el.selectedIndex].getAttribute('type')
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
@ -639,6 +878,13 @@ function retrieveReference(el) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a reference by sending a POST request to the server with the selected type,
|
||||||
|
* file, and text values. Displays an alert with the response message, and clears
|
||||||
|
* the reference and file input fields.
|
||||||
|
*
|
||||||
|
* @return {Promise} A Promise that resolves with the response message from the server.
|
||||||
|
*/
|
||||||
function saveReference() {
|
function saveReference() {
|
||||||
var select = document.querySelector('#references');
|
var select = document.querySelector('#references');
|
||||||
fetch('/index.php/save-reference', {
|
fetch('/index.php/save-reference', {
|
||||||
@ -661,6 +907,12 @@ function saveReference() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Previews a note by rendering the markdown content of the note in a preview section.
|
||||||
|
* Toggles between the note text and preview sections.
|
||||||
|
*
|
||||||
|
* @return {void} This function does not return anything.
|
||||||
|
*/
|
||||||
function previewNote() {
|
function previewNote() {
|
||||||
var noteText = document.querySelector('#notes');
|
var noteText = document.querySelector('#notes');
|
||||||
var notePreview = document.querySelector('#notePreview');
|
var notePreview = document.querySelector('#notePreview');
|
||||||
@ -688,6 +940,11 @@ function previewNote() {
|
|||||||
findLinks();
|
findLinks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds all links in the note preview and adds event listeners to them.
|
||||||
|
*
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
function findLinks() {
|
function findLinks() {
|
||||||
var links = document.querySelector('#notePreview').querySelectorAll('a');
|
var links = document.querySelector('#notePreview').querySelectorAll('a');
|
||||||
|
|
||||||
@ -730,6 +987,9 @@ function findLinks() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function that finds reference links and fetches passage data when clicked.
|
||||||
|
*/
|
||||||
function findRefLinks() {
|
function findRefLinks() {
|
||||||
var links = document.querySelector('#ref').querySelectorAll('a');
|
var links = document.querySelector('#ref').querySelectorAll('a');
|
||||||
|
|
||||||
@ -772,6 +1032,13 @@ function findRefLinks() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a passage in a popup element relative to the cursor position.
|
||||||
|
*
|
||||||
|
* @param {Event} event - The event that triggered the function.
|
||||||
|
* @param {string} text - The text to be displayed in the popup.
|
||||||
|
* @return {void} This function does not return a value.
|
||||||
|
*/
|
||||||
function showPassage(event, text) {
|
function showPassage(event, text) {
|
||||||
// Create a new div element for the popup
|
// Create a new div element for the popup
|
||||||
const popup = document.querySelector('#passage-popup');
|
const popup = document.querySelector('#passage-popup');
|
||||||
@ -787,12 +1054,23 @@ function showPassage(event, text) {
|
|||||||
popup.style.display = 'block';
|
popup.style.display = 'block';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the passage popup by clearing its content and hiding it.
|
||||||
|
*
|
||||||
|
* @return {void} This function does not return anything.
|
||||||
|
*/
|
||||||
function closePopup() {
|
function closePopup() {
|
||||||
const popup = document.querySelector('#passage-popup');
|
const popup = document.querySelector('#passage-popup');
|
||||||
popup.innerHTML = '';
|
popup.innerHTML = '';
|
||||||
popup.style.display = 'none';
|
popup.style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles the visibility of the note list and reference elements.
|
||||||
|
*
|
||||||
|
* @param {boolean} [openSidebar=true] - Whether to open the sidebar after toggling the visibility.
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
function openNote(openSidebar = true) {
|
function openNote(openSidebar = true) {
|
||||||
const noteList = document.querySelector('#note-list');
|
const noteList = document.querySelector('#note-list');
|
||||||
const refs = document.querySelector('#ref');
|
const refs = document.querySelector('#ref');
|
||||||
@ -810,6 +1088,13 @@ function openNote(openSidebar = true) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a note from the server based on the provided ID.
|
||||||
|
*
|
||||||
|
* @param {string} id - The ID of the note to retrieve.
|
||||||
|
* @param {boolean} [runOpen=true] - Whether to open the note sidebar after retrieving the note.
|
||||||
|
* @return {Promise<void>} A promise that resolves when the note is successfully retrieved and the UI is updated.
|
||||||
|
*/
|
||||||
function retrieveNote(id, runOpen = true) {
|
function retrieveNote(id, runOpen = true) {
|
||||||
fetch('/index.php/get-note', {
|
fetch('/index.php/get-note', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -857,11 +1142,84 @@ function retrieveNote(id, runOpen = true) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the share note functionality.
|
||||||
|
*/
|
||||||
|
function openShareNote() {
|
||||||
|
var id = document.querySelector('#noteId').value;
|
||||||
|
if (!id) {
|
||||||
|
alert('No Open Note Found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bd = document.querySelector('#modal-backdrop');
|
||||||
|
bd.style.display = 'block';
|
||||||
|
cont = document.querySelector('#modal-container');
|
||||||
|
cont.style.display = bd.style.display;
|
||||||
|
|
||||||
|
emailCont = document.querySelector('#modal-container');
|
||||||
|
emailCont.style.left = ((window.innerWidth / 2) - (emailCont.clientWidth / 2)) + 'px';
|
||||||
|
emailCont.style.top = ((window.innerHeight / 2) - (emailCont.clientHeight / 2)) + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the share note modal by hiding the backdrop and container,
|
||||||
|
* and clears the email input value.
|
||||||
|
*/
|
||||||
|
function closeShareNote() {
|
||||||
|
var bd = document.querySelector('#modal-backdrop');
|
||||||
|
var cont = document.querySelector('#modal-container');
|
||||||
|
bd.style.display = 'none';
|
||||||
|
cont.style.display = 'none';
|
||||||
|
document.querySelector('#shareEmail').value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to share a note by sending the note ID and email to the server.
|
||||||
|
*/
|
||||||
|
function shareNote(event) {
|
||||||
|
var id = document.querySelector('#noteId').value;
|
||||||
|
var email = document.querySelector('#shareEmail').value;
|
||||||
|
if (!id || !email) {
|
||||||
|
alert('Invalid Input');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch('/index.php/share-note', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
'id': id,
|
||||||
|
'email': email
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(result => {
|
||||||
|
if (result) {
|
||||||
|
alert(result.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
closeShareNote();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increases the font size of the element with the id 'ref' by 1 point.
|
||||||
|
*
|
||||||
|
* @return {void} This function does not return a value.
|
||||||
|
*/
|
||||||
function increaseFont() {
|
function increaseFont() {
|
||||||
var currentSize = document.querySelector('#ref').style.fontSize;
|
var currentSize = document.querySelector('#ref').style.fontSize;
|
||||||
document.querySelector('#ref').style.fontSize = (parseInt(currentSize) + 1) + 'pt';
|
document.querySelector('#ref').style.fontSize = (parseInt(currentSize) + 1) + 'pt';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decreases the font size of the element with the id 'ref' by 1 point.
|
||||||
|
*
|
||||||
|
* @return {void} This function does not return a value.
|
||||||
|
*/
|
||||||
function decreaseFont() {
|
function decreaseFont() {
|
||||||
var currentSize = document.querySelector('#ref').style.fontSize;
|
var currentSize = document.querySelector('#ref').style.fontSize;
|
||||||
document.querySelector('#ref').style.fontSize = (parseInt(currentSize) - 1) + 'pt';
|
document.querySelector('#ref').style.fontSize = (parseInt(currentSize) - 1) + 'pt';
|
||||||
|
1
public/js/script.min.js
vendored
Normal file
1
public/js/script.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -2233,7 +2233,6 @@ a.image:hover img {
|
|||||||
ol {
|
ol {
|
||||||
list-style: decimal;
|
list-style: decimal;
|
||||||
margin: 0 0 2em 0;
|
margin: 0 0 2em 0;
|
||||||
padding-left: 1.5em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ol li {
|
ol li {
|
||||||
@ -2243,7 +2242,6 @@ ol li {
|
|||||||
ul {
|
ul {
|
||||||
list-style: disc;
|
list-style: disc;
|
||||||
margin: 0 0 2em 0;
|
margin: 0 0 2em 0;
|
||||||
padding-left: 1em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.alt {
|
ul.alt {
|
||||||
@ -3088,13 +3086,13 @@ button:disabled,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#main>.inner {
|
#main>.inner {
|
||||||
padding: 0 0.5em 0.1em 0.5em;
|
padding: 0 0.25em 0.1em 0.25em;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
max-width: 110em;
|
max-width: 110em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#main>.inner>section {
|
#main>.inner>section {
|
||||||
padding: 0.5em 0 0.5em 0;
|
padding: 0.25em 0 0.25em 0;
|
||||||
border-top: solid 2px rgba(210, 215, 217, 0.75);
|
border-top: solid 2px rgba(210, 215, 217, 0.75);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3104,13 +3102,13 @@ button:disabled,
|
|||||||
|
|
||||||
@media screen and (max-width: 1680px) {
|
@media screen and (max-width: 1680px) {
|
||||||
#main>.inner {
|
#main>.inner {
|
||||||
padding: 0 0 0 2em;
|
padding: 0 0 0 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 1280px) {
|
@media screen and (max-width: 1280px) {
|
||||||
#main>.inner {
|
#main>.inner {
|
||||||
padding: 0 0 0 2em;
|
padding: 0 0 0 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3229,9 +3227,9 @@ button:disabled,
|
|||||||
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
|
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
|
||||||
border: 0;
|
border: 0;
|
||||||
display: block;
|
display: block;
|
||||||
height: 7.5em;
|
height: 4.5em;
|
||||||
left: 26em;
|
left: 26em;
|
||||||
line-height: 7.5em;
|
line-height: 4.5em;
|
||||||
outline: 0;
|
outline: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -3289,11 +3287,13 @@ button:disabled,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#sidebar .toggle {
|
#sidebar .toggle {
|
||||||
height: 6.25em;
|
height: 4.5em;
|
||||||
left: 24em;
|
left: 24em;
|
||||||
line-height: 6.25em;
|
line-height: 4.5em;
|
||||||
text-indent: 5em;
|
text-indent: 5em;
|
||||||
width: 5em;
|
width: 5em;
|
||||||
|
background-color: #fff;
|
||||||
|
margin-left: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidebar .toggle:before {
|
#sidebar .toggle:before {
|
||||||
@ -3338,7 +3338,7 @@ button:disabled,
|
|||||||
|
|
||||||
#sidebar .toggle {
|
#sidebar .toggle {
|
||||||
text-indent: 6em;
|
text-indent: 6em;
|
||||||
width: 6em;
|
width: 4.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidebar .toggle:before {
|
#sidebar .toggle:before {
|
||||||
|
@ -4,6 +4,7 @@ namespace App\Controller;
|
|||||||
|
|
||||||
use DateTime;
|
use DateTime;
|
||||||
|
|
||||||
|
use Parsedown;
|
||||||
use App\Entity\Reference;
|
use App\Entity\Reference;
|
||||||
use App\Entity\Template;
|
use App\Entity\Template;
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
@ -11,10 +12,14 @@ use App\Entity\Bible;
|
|||||||
use App\Entity\Speaker;
|
use App\Entity\Speaker;
|
||||||
use App\Entity\Series;
|
use App\Entity\Series;
|
||||||
use App\Entity\Note;
|
use App\Entity\Note;
|
||||||
|
use App\Entity\NoteShares;
|
||||||
|
use App\Utils\Utils;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Mailer\MailerInterface;
|
||||||
|
use Symfony\Component\Mime\Address;
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
|
||||||
class AjaxController extends AbstractController
|
class AjaxController extends AbstractController
|
||||||
@ -166,6 +171,7 @@ class AjaxController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReferenceController::$emi = $emi;
|
ReferenceController::$emi = $emi;
|
||||||
|
$user = $this->getUser();
|
||||||
|
|
||||||
$ret = match(strtolower($data->type)) {
|
$ret = match(strtolower($data->type)) {
|
||||||
'bible' => ReferenceController::retrieveBible("{$data->book} {$search}"),
|
'bible' => ReferenceController::retrieveBible("{$data->book} {$search}"),
|
||||||
@ -175,7 +181,14 @@ class AjaxController extends AbstractController
|
|||||||
'wcf' => ReferenceController::retrieveWCF($ref),
|
'wcf' => ReferenceController::retrieveWCF($ref),
|
||||||
'wsc' => ReferenceController::retrieveWSC($ref),
|
'wsc' => ReferenceController::retrieveWSC($ref),
|
||||||
'wlc' => ReferenceController::retrieveWLC($ref),
|
'wlc' => ReferenceController::retrieveWLC($ref),
|
||||||
'creed' => ReferenceController::retrieveCreed($data->book)
|
'lbc' => ReferenceController::retrieveLBC($ref),
|
||||||
|
'creed' => ReferenceController::retrieveCreed($data->book),
|
||||||
|
'39a' => ReferenceController::retrieve39a($ref),
|
||||||
|
'1hc' => ReferenceController::retrieve1HC($ref),
|
||||||
|
'2hc' => ReferenceController::retrieve2HC($ref),
|
||||||
|
'sd' => ReferenceController::retrieveSD($ref),
|
||||||
|
'agc' => ReferenceController::retrieveAGC($ref),
|
||||||
|
'note' => ReferenceController::retrieveNote($user)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!is_a($ret, Reference::class)) {
|
if (!is_a($ret, Reference::class)) {
|
||||||
@ -195,19 +208,12 @@ class AjaxController extends AbstractController
|
|||||||
{
|
{
|
||||||
$res = new Response();
|
$res = new Response();
|
||||||
$data = json_decode($req->getContent());
|
$data = json_decode($req->getContent());
|
||||||
$ret = match ($data->type) {
|
$ref = $emi->getRepository(Reference::class)->find($data->id);
|
||||||
'creed' => '/Creeds/',
|
|
||||||
'bc' => '/Belgic/',
|
|
||||||
'hc' => '/Heidelberg/',
|
|
||||||
'cd' => '/Dort/',
|
|
||||||
'wcf' => '/Westminster/Confessions/',
|
|
||||||
'wsc' => '/Westminster/Shorter Catechism/',
|
|
||||||
'wlc' => '/Westminster/Larger Catechism/'
|
|
||||||
};
|
|
||||||
|
|
||||||
$fc = file_get_contents(dirname(dirname(__DIR__))."/references{$ret}{$data->file}");
|
if (!is_a($ref, Reference::class)) {
|
||||||
|
$ref = new Reference();
|
||||||
$res->setContent(json_encode(['text' => $fc]));
|
}
|
||||||
|
$res->setContent(json_encode(['text' => $ref->getContent()]));
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
@ -224,7 +230,13 @@ class AjaxController extends AbstractController
|
|||||||
'cd' => 'Dort',
|
'cd' => 'Dort',
|
||||||
'wcf' => 'Westminster/Confessions',
|
'wcf' => 'Westminster/Confessions',
|
||||||
'wsc' => 'Westminster/Shorter Catechism',
|
'wsc' => 'Westminster/Shorter Catechism',
|
||||||
'wlc' => 'Westminster/Larger Catechism'
|
'wlc' => 'Westminster/Larger Catechism',
|
||||||
|
'lbc' => 'London',
|
||||||
|
'39a' => '39 Articles',
|
||||||
|
'1hc' => '1 Helvetic Catechism',
|
||||||
|
'2hc' => '2 Helvetic Catechism',
|
||||||
|
'sd' => 'Savor Declaration',
|
||||||
|
'agc' => 'Augsburg Confession'
|
||||||
};
|
};
|
||||||
|
|
||||||
$ret = file_put_contents(dirname(dirname(__DIR__))."/references/{$path}/{$data->file}", $data->text);
|
$ret = file_put_contents(dirname(dirname(__DIR__))."/references/{$path}/{$data->file}", $data->text);
|
||||||
@ -251,6 +263,18 @@ class AjaxController extends AbstractController
|
|||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[Route('/get-notes', name: 'app_get_notes')]
|
||||||
|
public function getNotes(EntityManagerInterface $emi): Response
|
||||||
|
{
|
||||||
|
/** @var User $user */
|
||||||
|
$user = $this->getUser();
|
||||||
|
$notes = $emi->getRepository(Note::class)->reverseNoteSort($user);
|
||||||
|
$res = new Response();
|
||||||
|
$res->setContent(json_encode(['data'=> $notes]));
|
||||||
|
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
#[Route('/get-note', name: 'app_get_note')]
|
#[Route('/get-note', name: 'app_get_note')]
|
||||||
public function getNote(Request $req, EntityManagerInterface $emi): Response
|
public function getNote(Request $req, EntityManagerInterface $emi): Response
|
||||||
{
|
{
|
||||||
@ -274,6 +298,10 @@ class AjaxController extends AbstractController
|
|||||||
if (is_array($note) && count($note) > 0) {
|
if (is_array($note) && count($note) > 0) {
|
||||||
/** @var Note $note */
|
/** @var Note $note */
|
||||||
$note = $note[0];
|
$note = $note[0];
|
||||||
|
} else {
|
||||||
|
$note = new Note();
|
||||||
|
$newNote = true;
|
||||||
|
$note->setUser($this->getUser());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$note = new Note();
|
$note = new Note();
|
||||||
@ -293,6 +321,7 @@ class AjaxController extends AbstractController
|
|||||||
->setSpeaker($speaker)
|
->setSpeaker($speaker)
|
||||||
->setText($data->note)
|
->setText($data->note)
|
||||||
->setPassage($data->passage)
|
->setPassage($data->passage)
|
||||||
|
->setRecording($data->recording)
|
||||||
->setRefs($refs);
|
->setRefs($refs);
|
||||||
|
|
||||||
$emi->persist($note);
|
$emi->persist($note);
|
||||||
@ -308,7 +337,7 @@ class AjaxController extends AbstractController
|
|||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/discard-note', name: 'app_discard_note', methods: ['POST'])]
|
#[Route('/delete-note', name: 'app_discard_note', methods: ['POST'])]
|
||||||
public function discardNote(Request $req, EntityManagerInterface $emi): Response
|
public function discardNote(Request $req, EntityManagerInterface $emi): Response
|
||||||
{
|
{
|
||||||
$data = json_decode($req->getContent());
|
$data = json_decode($req->getContent());
|
||||||
@ -323,6 +352,61 @@ class AjaxController extends AbstractController
|
|||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[Route('/share-note', name: 'app_share_note', methods: ['POST'])]
|
||||||
|
public function shareNote(Request $req, EntityManagerInterface $emi, MailerInterface $mailer): Response
|
||||||
|
{
|
||||||
|
$data = json_decode($req->getContent());
|
||||||
|
$note = $emi->getRepository(Note::class)->find($data->id);
|
||||||
|
/** @var User $user */
|
||||||
|
$user = $this->getUser();
|
||||||
|
$shared = $emi->getRepository(User::class)->findBy(['email' => $data->email]);
|
||||||
|
$email = $data->email;
|
||||||
|
$isRegistered = false;
|
||||||
|
|
||||||
|
if (!$note) {
|
||||||
|
$res = new Response();
|
||||||
|
$res->setContent(json_encode([
|
||||||
|
'msg' => 'Note Not Found'
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($shared) && count($shared) > 0) {
|
||||||
|
$ns = new NoteShares();
|
||||||
|
$ns->setNote($note)
|
||||||
|
->setOwner($user)
|
||||||
|
->setShare($shared[0]);
|
||||||
|
$emi->persist($ns);
|
||||||
|
$emi->flush();
|
||||||
|
|
||||||
|
$email = $shared[0]->getEmail();
|
||||||
|
$isRegistered = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$Parsedown = new Parsedown();
|
||||||
|
|
||||||
|
$util = new Utils();
|
||||||
|
$util->sendEmail(
|
||||||
|
$mailer,
|
||||||
|
new Address('ryan@rkprather.com', 'Sermon Notes'),
|
||||||
|
new Address($email),
|
||||||
|
'Note Shared',
|
||||||
|
$this->renderView('emails/note-shared.html.twig', [
|
||||||
|
'note' => $note,
|
||||||
|
'owner' => $user,
|
||||||
|
'isRegistered' => $isRegistered,
|
||||||
|
'formattedText' => $Parsedown->text($note->getText()),
|
||||||
|
'domain' => $_ENV['DOMAIN'],
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
$res = new Response();
|
||||||
|
$res->setContent(json_encode([
|
||||||
|
'msg' => 'shared'
|
||||||
|
]));
|
||||||
|
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
#[Route('/get-passage/{passage}', name: 'app_get_passage')]
|
#[Route('/get-passage/{passage}', name: 'app_get_passage')]
|
||||||
public function getPassage($passage, EntityManagerInterface $emi): Response
|
public function getPassage($passage, EntityManagerInterface $emi): Response
|
||||||
{
|
{
|
||||||
@ -363,4 +447,52 @@ class AjaxController extends AbstractController
|
|||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[Route('/save-settings', name: 'app_save_settings', methods: ['POST'])]
|
||||||
|
public function saveSettings(Request $req, EntityManagerInterface $emi): Response
|
||||||
|
{
|
||||||
|
$data = json_decode($req->getContent());
|
||||||
|
/** @var User $user */
|
||||||
|
$user = $this->getUser();
|
||||||
|
|
||||||
|
if (!$user) {
|
||||||
|
return new Response(json_encode([
|
||||||
|
'msg' => 'No User'
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$data->saveInterval) {
|
||||||
|
$data->saveInterval = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$data->saveReferences) {
|
||||||
|
$data->saveReferences = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$data->noteTextSize) {
|
||||||
|
$data->noteTextSize = 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$data->trackSaveSize) {
|
||||||
|
$data->trackSaveSize = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$meta = $user->getMetaData();
|
||||||
|
$meta['saveInterval'] = $data->saveInterval;
|
||||||
|
$meta['saveReferences'] = $data->saveReferences;
|
||||||
|
$meta['noteTextSize'] = $data->noteTextSize;
|
||||||
|
$meta['trackSaveSize'] = $data->trackSaveSize;
|
||||||
|
$meta['saveTimeout'] = $data->saveTimeout;
|
||||||
|
$meta['save-failure-count'] = $data->saveFailureCount;
|
||||||
|
$user->setMetaData($meta);
|
||||||
|
$emi->persist($user);
|
||||||
|
$emi->flush();
|
||||||
|
|
||||||
|
$res = new Response();
|
||||||
|
$res->setContent(json_encode([
|
||||||
|
'msg' => 'Settings Saved'
|
||||||
|
]));
|
||||||
|
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
namespace App\Controller;
|
namespace App\Controller;
|
||||||
|
|
||||||
use App\Entity\Note;
|
use App\Entity\Note;
|
||||||
use App\Entity\Reference;
|
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
@ -11,13 +10,15 @@ use Symfony\Component\HttpFoundation\Request;
|
|||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
use Symfony\Component\Security\Http\Attribute\CurrentUser;
|
use Symfony\Component\Security\Http\Attribute\CurrentUser;
|
||||||
use Symfony\Component\Uid\Uuid;
|
|
||||||
|
|
||||||
class DefaultController extends AbstractController
|
class DefaultController extends AbstractController
|
||||||
{
|
{
|
||||||
#[Route('/', name: 'app_index')]
|
#[Route('/', name: 'app_index')]
|
||||||
public function index(): Response
|
public function index(): Response
|
||||||
{
|
{
|
||||||
|
if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
|
||||||
|
return $this->redirect('/index.php/home');
|
||||||
|
}
|
||||||
return $this->render('default/index.html.twig');
|
return $this->render('default/index.html.twig');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,11 +28,47 @@ class DefaultController extends AbstractController
|
|||||||
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
|
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
|
||||||
$last4Notes = $emi->getRepository(Note::class)->getLast4Notes($user);
|
$last4Notes = $emi->getRepository(Note::class)->getLast4Notes($user);
|
||||||
$openNotes = $emi->getRepository(Note::class)->reverseNoteSort($user);
|
$openNotes = $emi->getRepository(Note::class)->reverseNoteSort($user);
|
||||||
|
$meta = $user->getMetaData();
|
||||||
|
|
||||||
return $this->render('default/home.html.twig', [
|
return $this->render('default/home.html.twig', [
|
||||||
'last4Notes' => $last4Notes,
|
'last4Notes' => $last4Notes,
|
||||||
'reverseNoteSort' => $openNotes,
|
'reverseNoteSort' => $openNotes,
|
||||||
'isAdmin' => $this->isGranted('ROLE_ADMIN'),
|
'isAdmin' => $this->isGranted('ROLE_ADMIN'),
|
||||||
|
'meta' => $meta,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/cheat-sheet', name: 'app_cheat_sheet')]
|
||||||
|
public function cheatSheet(): Response
|
||||||
|
{
|
||||||
|
return $this->render('default/cheat-sheet.html.twig');
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/profile', name: 'app_profile')]
|
||||||
|
public function profile(): Response
|
||||||
|
{
|
||||||
|
/** @var User $user */
|
||||||
|
$user = $this->getUser();
|
||||||
|
if (!$user) {
|
||||||
|
return $this->redirectToRoute('app_login');
|
||||||
|
}
|
||||||
|
$meta = $user->getMetaData();
|
||||||
|
if (!$meta) {
|
||||||
|
$meta = [
|
||||||
|
'saveInterval' => 15,
|
||||||
|
'saveReferences' => 'checked',
|
||||||
|
'noteTextSize' => 12,
|
||||||
|
'trackSaveSize' => null,
|
||||||
|
'saveFailureCount' => 3,
|
||||||
|
'saveTimeout' => 5,
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
$meta['saveReferences'] = $meta['saveReferences'] ? 'checked' : null;
|
||||||
|
$meta['trackSaveSize'] = $meta['trackSaveSize'] ? 'checked' : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('default/profile.html.twig', [
|
||||||
|
'meta' => $meta,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,23 +77,7 @@ class DefaultController extends AbstractController
|
|||||||
{
|
{
|
||||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||||
|
|
||||||
$creeds = $emi->getRepository(Reference::class)->findByType('creed');
|
return $this->render('editors/reference-editor.html.twig');
|
||||||
$belgic = $emi->getRepository(Reference::class)->findByType('belgic');
|
|
||||||
$heidelberg = $emi->getRepository(Reference::class)->findByType('heidelberg');
|
|
||||||
$dort = $emi->getRepository(Reference::class)->findByType('dort');
|
|
||||||
$wcf = $emi->getRepository(Reference::class)->findByType('wcf');
|
|
||||||
$wsc = $emi->getRepository(Reference::class)->findByType('wsc');
|
|
||||||
$wlc = $emi->getRepository(Reference::class)->findByType('wlc');
|
|
||||||
|
|
||||||
return $this->render('editors/reference-editor.html.twig', [
|
|
||||||
'creeds' => $creeds,
|
|
||||||
'belgic' => $belgic,
|
|
||||||
'heidelberg' => $heidelberg,
|
|
||||||
'dort' => $dort,
|
|
||||||
'wcf' => $wcf,
|
|
||||||
'wsc' => $wsc,
|
|
||||||
'wlc' => $wlc
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/template-editor', name: 'app_template_editor')]
|
#[Route('/template-editor', name: 'app_template_editor')]
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
namespace App\Controller;
|
namespace App\Controller;
|
||||||
|
|
||||||
use App\Entity\Bible;
|
use App\Entity\Bible;
|
||||||
|
use App\Entity\Note;
|
||||||
use App\Entity\Reference;
|
use App\Entity\Reference;
|
||||||
|
use App\Entity\User;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
@ -144,6 +146,9 @@ class ReferenceController extends AbstractController
|
|||||||
public static function retrieveWSC($ref): Reference
|
public static function retrieveWSC($ref): Reference
|
||||||
{
|
{
|
||||||
$r = self::$emi->getRepository(Reference::class)->findBy(['type' => $ref->getType(), 'ndx' => $ref->getNdx()]);
|
$r = self::$emi->getRepository(Reference::class)->findBy(['type' => $ref->getType(), 'ndx' => $ref->getNdx()]);
|
||||||
|
if (!$r) {
|
||||||
|
return new Reference();
|
||||||
|
}
|
||||||
return $r[0];
|
return $r[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,6 +162,9 @@ class ReferenceController extends AbstractController
|
|||||||
public static function retrieveWLC($ref): Reference
|
public static function retrieveWLC($ref): Reference
|
||||||
{
|
{
|
||||||
$r = self::$emi->getRepository(Reference::class)->findBy(['type' => $ref->getType(), 'ndx' => $ref->getNdx()]);
|
$r = self::$emi->getRepository(Reference::class)->findBy(['type' => $ref->getType(), 'ndx' => $ref->getNdx()]);
|
||||||
|
if (!$r) {
|
||||||
|
return new Reference();
|
||||||
|
}
|
||||||
return $r[0];
|
return $r[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,6 +178,79 @@ class ReferenceController extends AbstractController
|
|||||||
public static function retrieveWCF($ref): Reference
|
public static function retrieveWCF($ref): Reference
|
||||||
{
|
{
|
||||||
$r = self::$emi->getRepository(Reference::class)->findBy(['type' => $ref->getType(), 'ndx' => $ref->getNdx()]);
|
$r = self::$emi->getRepository(Reference::class)->findBy(['type' => $ref->getType(), 'ndx' => $ref->getNdx()]);
|
||||||
|
if (!$r) {
|
||||||
|
return new Reference();
|
||||||
|
}
|
||||||
return $r[0];
|
return $r[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function retrieveLBC($ref): Reference
|
||||||
|
{
|
||||||
|
$r = self::$emi->getRepository(Reference::class)->findBy(['type' => 'lbc', 'ndx' => $ref->getNdx()]);
|
||||||
|
if (!$r) {
|
||||||
|
return new Reference();
|
||||||
|
}
|
||||||
|
return $r[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function retrieveAGC($ref): Reference
|
||||||
|
{
|
||||||
|
$r = self::$emi->getRepository(Reference::class)->findBy(['type' => 'agc', 'ndx' => $ref->getNdx()]);
|
||||||
|
if (!$r) {
|
||||||
|
return new Reference();
|
||||||
|
}
|
||||||
|
return $r[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function retrieve39a($ref): Reference
|
||||||
|
{
|
||||||
|
$r = self::$emi->getRepository(Reference::class)->findBy(['type' => '39a', 'ndx' => $ref->getNdx()]);
|
||||||
|
if (!$r) {
|
||||||
|
return new Reference();
|
||||||
|
}
|
||||||
|
return $r[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function retrieve1HC($ref): Reference
|
||||||
|
{
|
||||||
|
$r = self::$emi->getRepository(Reference::class)->findBy(['type' => '1hc', 'ndx' => $ref->getNdx()]);
|
||||||
|
if (!$r) {
|
||||||
|
return new Reference();
|
||||||
|
}
|
||||||
|
return $r[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function retrieve2HC($ref): Reference
|
||||||
|
{
|
||||||
|
$r = self::$emi->getRepository(Reference::class)->findBy(['type' => '2hc', 'ndx' => $ref->getNdx()]);
|
||||||
|
if (!$r) {
|
||||||
|
return new Reference();
|
||||||
|
}
|
||||||
|
return $r[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function retrieveSD($ref): Reference
|
||||||
|
{
|
||||||
|
$r = self::$emi->getRepository(Reference::class)->findBy(['type' => 'sd', 'ndx' => $ref->getNdx()]);
|
||||||
|
if (!$r) {
|
||||||
|
return new Reference();
|
||||||
|
}
|
||||||
|
return $r[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function retrieveNote(?User $user): array
|
||||||
|
{
|
||||||
|
$notes = self::$emi->getRepository(Note::class)->findBy(['user' => $user], ['date' => 'DESC']);
|
||||||
|
return $notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/reference/{type}', name: 'app_reference_by_type', methods: ['GET'])]
|
||||||
|
public function retrieveReferenceByType(string $type, EntityManagerInterface $emi): Response
|
||||||
|
{
|
||||||
|
$res = new Response();
|
||||||
|
$data = $emi->getRepository(Reference::class)->findByType($type);
|
||||||
|
|
||||||
|
$res->setContent(json_encode($data));
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,18 +4,25 @@ namespace App\Controller;
|
|||||||
|
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
use App\Form\RegistrationFormType;
|
use App\Form\RegistrationFormType;
|
||||||
|
use App\Utils\Utils;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Mailer\MailerInterface;
|
||||||
|
use Symfony\Component\Mime\Address;
|
||||||
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
|
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
|
||||||
class RegistrationController extends AbstractController
|
class RegistrationController extends AbstractController
|
||||||
{
|
{
|
||||||
#[Route('/register', name: 'app_register')]
|
#[Route('/register', name: 'app_register')]
|
||||||
public function register(Request $request, UserPasswordHasherInterface $userPasswordHasher, EntityManagerInterface $entityManager): Response
|
public function register(
|
||||||
{
|
Request $request,
|
||||||
|
UserPasswordHasherInterface $userPasswordHasher,
|
||||||
|
EntityManagerInterface $entityManager,
|
||||||
|
MailerInterface $mailer
|
||||||
|
): Response {
|
||||||
$user = new User();
|
$user = new User();
|
||||||
|
|
||||||
$form = $this->createForm(RegistrationFormType::class, $user);
|
$form = $this->createForm(RegistrationFormType::class, $user);
|
||||||
@ -39,6 +46,8 @@ class RegistrationController extends AbstractController
|
|||||||
$entityManager->persist($user);
|
$entityManager->persist($user);
|
||||||
$entityManager->flush();
|
$entityManager->flush();
|
||||||
|
|
||||||
|
$this->sendEmail($user, $mailer);
|
||||||
|
|
||||||
return $this->redirectToRoute('app_home');
|
return $this->redirectToRoute('app_home');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,4 +55,18 @@ class RegistrationController extends AbstractController
|
|||||||
'registrationForm' => $form,
|
'registrationForm' => $form,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function sendEmail(User $user, MailerInterface $mailer): void
|
||||||
|
{
|
||||||
|
$util = new Utils();
|
||||||
|
$util->sendEmail(
|
||||||
|
$mailer,
|
||||||
|
new Address('ryan@rkprather.com'),
|
||||||
|
new Address('ryan@rkprather.com'),
|
||||||
|
'New Account',
|
||||||
|
$this->renderView('emails/registration.html.twig', [
|
||||||
|
'user' => $user
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,9 @@ class Note implements JsonSerializable
|
|||||||
#[ORM\ManyToOne(inversedBy: 'notes')]
|
#[ORM\ManyToOne(inversedBy: 'notes')]
|
||||||
private ?User $user = null;
|
private ?User $user = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 255, nullable: true)]
|
||||||
|
private ?string $recording = null;
|
||||||
|
|
||||||
public function getId(): ?Uuid
|
public function getId(): ?Uuid
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
@ -166,12 +169,21 @@ class Note implements JsonSerializable
|
|||||||
{
|
{
|
||||||
return "<a href='#' onclick=\"retrieveNote('{$this->id}')\">".
|
return "<a href='#' onclick=\"retrieveNote('{$this->id}')\">".
|
||||||
$this->title.
|
$this->title.
|
||||||
"</a>";
|
"</a> ".
|
||||||
|
"<a href='#' onclick=\"deleteNote('{$this->id}', this)\">".
|
||||||
|
"<i class='fas fa-trash-alt'></i>".
|
||||||
|
"</a>".
|
||||||
|
(
|
||||||
|
$this->recording ? "<br/>".
|
||||||
|
"<a href='{$this->recording}' target='_blank' class='recording-link'>".
|
||||||
|
"<i class='fa fa-play-circle'></i>".
|
||||||
|
"</a>" : null
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toTableRow(): string
|
public function toTableRow(): string
|
||||||
{
|
{
|
||||||
return "<tr>".
|
return "<tr data-id='row-{$this->id->toHex()}'>".
|
||||||
"<td>{$this->toLink()}</td>".
|
"<td>{$this->toLink()}</td>".
|
||||||
"<td>{$this->speaker->getName()}</td>".
|
"<td>{$this->speaker->getName()}</td>".
|
||||||
"<td>{$this->passage}</td>".
|
"<td>{$this->passage}</td>".
|
||||||
@ -183,6 +195,7 @@ class Note implements JsonSerializable
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => $this->getId(),
|
'id' => $this->getId(),
|
||||||
|
'link' => $this->toLink(),
|
||||||
'title' => $this->getTitle(),
|
'title' => $this->getTitle(),
|
||||||
'date' => $this->getDate(),
|
'date' => $this->getDate(),
|
||||||
'passage' => $this->getPassage(),
|
'passage' => $this->getPassage(),
|
||||||
@ -193,4 +206,16 @@ class Note implements JsonSerializable
|
|||||||
'user' => $this->getUser(),
|
'user' => $this->getUser(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getRecording(): ?string
|
||||||
|
{
|
||||||
|
return $this->recording;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setRecording(?string $recording): static
|
||||||
|
{
|
||||||
|
$this->recording = $recording;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
106
src/Entity/NoteShares.php
Normal file
106
src/Entity/NoteShares.php
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
use App\Repository\NoteSharesRepository;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
#[ORM\Entity(repositoryClass: NoteSharesRepository::class)]
|
||||||
|
class NoteShares
|
||||||
|
{
|
||||||
|
#[ORM\Id]
|
||||||
|
#[ORM\GeneratedValue]
|
||||||
|
#[ORM\Column]
|
||||||
|
private ?int $id = null;
|
||||||
|
|
||||||
|
#[ORM\ManyToOne(inversedBy: 'noteShares')]
|
||||||
|
#[ORM\JoinColumn(nullable: false)]
|
||||||
|
private ?User $owner = null;
|
||||||
|
|
||||||
|
#[ORM\ManyToOne]
|
||||||
|
#[ORM\JoinColumn(nullable: false)]
|
||||||
|
private ?User $share = null;
|
||||||
|
|
||||||
|
#[ORM\ManyToOne]
|
||||||
|
#[ORM\JoinColumn(nullable: false)]
|
||||||
|
private ?Note $note = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the ID of the NoteShares entity.
|
||||||
|
*
|
||||||
|
* @return int|null The ID of the NoteShares entity, or null if not set.
|
||||||
|
*/
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the owner of the object.
|
||||||
|
*
|
||||||
|
* @return User|null The owner of the object, or null if not set.
|
||||||
|
*/
|
||||||
|
public function getOwner(): ?User
|
||||||
|
{
|
||||||
|
return $this->owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A description of the entire PHP function.
|
||||||
|
*
|
||||||
|
* @param User|null $owner description
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function setOwner(?User $owner): static
|
||||||
|
{
|
||||||
|
$this->owner = $owner;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the share for the current instance.
|
||||||
|
*
|
||||||
|
* @return User|null The user who shares this instance.
|
||||||
|
*/
|
||||||
|
public function getShare(): ?User
|
||||||
|
{
|
||||||
|
return $this->share;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the share for the current instance.
|
||||||
|
*
|
||||||
|
* @param User|null $share The user to set as the share.
|
||||||
|
* @return static The current instance.
|
||||||
|
*/
|
||||||
|
public function setShare(?User $share): static
|
||||||
|
{
|
||||||
|
$this->share = $share;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the associated Note object.
|
||||||
|
*
|
||||||
|
* @return Note|null The associated Note object, or null if not found.
|
||||||
|
*/
|
||||||
|
public function getNote(): ?Note
|
||||||
|
{
|
||||||
|
return $this->note;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the note for this NoteShares entity.
|
||||||
|
*
|
||||||
|
* @param Note|null $note The note to set
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function setNote(?Note $note): static
|
||||||
|
{
|
||||||
|
$this->note = $note;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,7 @@ use Symfony\Bridge\Doctrine\Types\UuidType;
|
|||||||
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
use Symfony\Component\Uid\Uuid;
|
use Symfony\Component\Uid\Uuid;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
#[ORM\Entity(repositoryClass: UserRepository::class)]
|
#[ORM\Entity(repositoryClass: UserRepository::class)]
|
||||||
#[ORM\UniqueConstraint(name: 'UNIQ_IDENTIFIER_EMAIL', fields: ['email'])]
|
#[ORM\UniqueConstraint(name: 'UNIQ_IDENTIFIER_EMAIL', fields: ['email'])]
|
||||||
@ -23,6 +24,9 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface, JsonSer
|
|||||||
private ?Uuid $id = null;
|
private ?Uuid $id = null;
|
||||||
|
|
||||||
#[ORM\Column(length: 180)]
|
#[ORM\Column(length: 180)]
|
||||||
|
#[Assert\Email(
|
||||||
|
message: 'The email {{ value }} is not a valid email.',
|
||||||
|
)]
|
||||||
private ?string $email = null;
|
private ?string $email = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,12 +68,22 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface, JsonSer
|
|||||||
#[ORM\OneToMany(targetEntity: Note::class, mappedBy: 'user')]
|
#[ORM\OneToMany(targetEntity: Note::class, mappedBy: 'user')]
|
||||||
private Collection $notes;
|
private Collection $notes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Collection<int, NoteShares>
|
||||||
|
*/
|
||||||
|
#[ORM\OneToMany(targetEntity: NoteShares::class, mappedBy: 'ownerId', orphanRemoval: true)]
|
||||||
|
private Collection $noteShares;
|
||||||
|
|
||||||
|
#[ORM\Column(nullable: true)]
|
||||||
|
private ?array $metaData = null;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->series = new ArrayCollection();
|
$this->series = new ArrayCollection();
|
||||||
$this->speakers = new ArrayCollection();
|
$this->speakers = new ArrayCollection();
|
||||||
$this->templates = new ArrayCollection();
|
$this->templates = new ArrayCollection();
|
||||||
$this->notes = new ArrayCollection();
|
$this->notes = new ArrayCollection();
|
||||||
|
$this->noteShares = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getId(): ?Uuid
|
public function getId(): ?Uuid
|
||||||
@ -77,6 +91,11 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface, JsonSer
|
|||||||
return $this->id;
|
return $this->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getHexId(): string
|
||||||
|
{
|
||||||
|
return $this->id->toHex();
|
||||||
|
}
|
||||||
|
|
||||||
public function setId(?Uuid $id): static
|
public function setId(?Uuid $id): static
|
||||||
{
|
{
|
||||||
$this->id = $id;
|
$this->id = $id;
|
||||||
@ -299,4 +318,46 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface, JsonSer
|
|||||||
'name' => $this->name,
|
'name' => $this->name,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection<int, NoteShares>
|
||||||
|
*/
|
||||||
|
public function getNoteShares(): Collection
|
||||||
|
{
|
||||||
|
return $this->noteShares;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addNoteShare(NoteShares $noteShare): static
|
||||||
|
{
|
||||||
|
if (!$this->noteShares->contains($noteShare)) {
|
||||||
|
$this->noteShares->add($noteShare);
|
||||||
|
$noteShare->setOwner($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeNoteShare(NoteShares $noteShare): static
|
||||||
|
{
|
||||||
|
if ($this->noteShares->removeElement($noteShare)) {
|
||||||
|
// set the owning side to null (unless already changed)
|
||||||
|
if ($noteShare->getOwner() === $this) {
|
||||||
|
$noteShare->setOwner(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMetaData(): ?array
|
||||||
|
{
|
||||||
|
return $this->metaData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setMetaData(?array $metaData): static
|
||||||
|
{
|
||||||
|
$this->metaData = $metaData;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
43
src/Repository/NoteSharesRepository.php
Normal file
43
src/Repository/NoteSharesRepository.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Repository;
|
||||||
|
|
||||||
|
use App\Entity\NoteShares;
|
||||||
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends ServiceEntityRepository<NoteShares>
|
||||||
|
*/
|
||||||
|
class NoteSharesRepository extends ServiceEntityRepository
|
||||||
|
{
|
||||||
|
public function __construct(ManagerRegistry $registry)
|
||||||
|
{
|
||||||
|
parent::__construct($registry, NoteShares::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @return NoteShares[] Returns an array of NoteShares objects
|
||||||
|
// */
|
||||||
|
// public function findByExampleField($value): array
|
||||||
|
// {
|
||||||
|
// return $this->createQueryBuilder('n')
|
||||||
|
// ->andWhere('n.exampleField = :val')
|
||||||
|
// ->setParameter('val', $value)
|
||||||
|
// ->orderBy('n.id', 'ASC')
|
||||||
|
// ->setMaxResults(10)
|
||||||
|
// ->getQuery()
|
||||||
|
// ->getResult()
|
||||||
|
// ;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public function findOneBySomeField($value): ?NoteShares
|
||||||
|
// {
|
||||||
|
// return $this->createQueryBuilder('n')
|
||||||
|
// ->andWhere('n.exampleField = :val')
|
||||||
|
// ->setParameter('val', $value)
|
||||||
|
// ->getQuery()
|
||||||
|
// ->getOneOrNullResult()
|
||||||
|
// ;
|
||||||
|
// }
|
||||||
|
}
|
35
src/Utils/Utils.php
Normal file
35
src/Utils/Utils.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Utils;
|
||||||
|
|
||||||
|
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
|
||||||
|
use Symfony\Component\Mailer\MailerInterface;
|
||||||
|
use Symfony\Component\Mime\Address;
|
||||||
|
use Symfony\Component\Mime\Email;
|
||||||
|
|
||||||
|
class Utils
|
||||||
|
{
|
||||||
|
public function sendEmail(MailerInterface $mailer, Address $from, Address $to, string $subject, string $content)
|
||||||
|
{
|
||||||
|
//$dsn = "smtp://{$_ENV['MAIL_USER']}:{$_ENV['MAIL_PWD']}@{$_ENV['MAIL_SERVER']}:{$_ENV['MAIL_PORT']}";
|
||||||
|
//dump($_ENV['MAILER_DSN']);
|
||||||
|
//$_ENV['MAILER_DSN'] = $dsn;
|
||||||
|
//dump($_ENV['MAILER_DSN']);
|
||||||
|
//die;
|
||||||
|
|
||||||
|
$mail = (new Email())
|
||||||
|
->from($from)
|
||||||
|
->to($to)
|
||||||
|
->subject($subject)
|
||||||
|
->replyTo($from)
|
||||||
|
->html($content);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$mailer->send($mail);
|
||||||
|
} catch (TransportExceptionInterface $e) {
|
||||||
|
die($e->getMessage());
|
||||||
|
// some error prevented the email sending; display an
|
||||||
|
// error message or try to resend the message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@
|
|||||||
<title>{% block title %}Welcome!{% endblock %}</title>
|
<title>{% block title %}Welcome!{% endblock %}</title>
|
||||||
{% block stylesheets %}{% endblock %}
|
{% block stylesheets %}{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
<body class='is-preload' onload='setHeight()' onresize='setHeight()'>
|
<body class='is-preload' onresize='setHeight()'>
|
||||||
{% block body %}{% endblock %}
|
{% block body %}{% endblock %}
|
||||||
{% block javascripts %}{% endblock %}
|
{% block javascripts %}{% endblock %}
|
||||||
</body>
|
</body>
|
||||||
|
163
templates/default/cheat-sheet.html.twig
Normal file
163
templates/default/cheat-sheet.html.twig
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
{% extends 'base.html.twig' %}
|
||||||
|
|
||||||
|
{% block title %}Markdown Cheat Sheet{% endblock %}
|
||||||
|
|
||||||
|
{% block stylesheets %}
|
||||||
|
<link href="/theme/assets/css/main.css" rel="stylesheet" />
|
||||||
|
<link href='/theme/assets/css/jquery-ui.theme.css' rel='stylesheet' />
|
||||||
|
<link href='/theme/assets/css/jquery-ui.structure.css' rel='stylesheet' />
|
||||||
|
<link href='/css/style.css' rel='stylesheet' />
|
||||||
|
<link href='//cdn.datatables.net/2.0.8/css/dataTables.dataTables.min.css' rel='stylesheet' />
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block javascripts %}
|
||||||
|
<script src="/theme/assets/js/jquery.min.js"></script>
|
||||||
|
<script src='/theme/assets/js/jquery-ui.js'></script>
|
||||||
|
<script src="/theme/assets/js/browser.min.js"></script>
|
||||||
|
<script src="/theme/assets/js/breakpoints.min.js"></script>
|
||||||
|
<script src="/theme/assets/js/util.js"></script>
|
||||||
|
<script src="/theme/assets/js/main.js"></script>
|
||||||
|
<script src='//momentjs.com/downloads/moment-with-locales.js'></script>
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/markdown-it/13.0.2/markdown-it.min.js" integrity="sha512-ohlWmsCxOu0bph1om5eDL0jm/83eH09fvqLDhiEdiqfDeJbEvz4FSbeY0gLJSVJwQAp0laRhTXbUQG+ZUuifUQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
|
<script src='//cdn.datatables.net/2.0.8/js/dataTables.min.js'></script>
|
||||||
|
<script src='/js/script.js'></script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<div style='padding-left:5px;'>
|
||||||
|
<h1>Markdown Cheat Sheet</h1>
|
||||||
|
|
||||||
|
<p>The following was provided by <a href='https://www.markdownguide.com'>The Markdown Guid</a></p>
|
||||||
|
|
||||||
|
<p> This Markdown cheat sheet provides a quick overview of all the Markdown syntax elements. It can't cover every edge case, so if you need more information about any of these elements, refere to the reference guides for <a href='//www.markdownguide.org/basic-syntax/'>basic syntax</a> and </a href='//www.markdownguide.org/extended-syntax/'>extended syntax</a>.</p>
|
||||||
|
|
||||||
|
<h2>Basic Syntax</h2>
|
||||||
|
|
||||||
|
<p>These are the elements outlined in John Gruberal's original design document. All Markdown applications support these elements. The quoted text is what is needed to render what is displayed right below</p>
|
||||||
|
|
||||||
|
<h3>Headings</h3>
|
||||||
|
|
||||||
|
"# H1"<br/>
|
||||||
|
<h1># H1</h1>
|
||||||
|
|
||||||
|
"## H2"<br/>
|
||||||
|
<h2>## H2</h2>
|
||||||
|
|
||||||
|
"### H3"<br/>
|
||||||
|
<h3>### H3</h3>
|
||||||
|
|
||||||
|
<h3>Bold</h3>
|
||||||
|
|
||||||
|
"**bold text**"<br/>
|
||||||
|
<strong>bold text</strong>
|
||||||
|
|
||||||
|
<h3>Italic</h3>
|
||||||
|
|
||||||
|
"*italicized text*"<br/>
|
||||||
|
<i>italicized text</i>
|
||||||
|
|
||||||
|
<h3>Blockquote</h3>
|
||||||
|
|
||||||
|
"> blockquote"<br/>
|
||||||
|
<blockquote>blockquote</blockquote>
|
||||||
|
|
||||||
|
<h3>Ordered List</h3>
|
||||||
|
|
||||||
|
"1. First item"<br/>
|
||||||
|
"2. Second item"<br/>
|
||||||
|
"3. Third item"<br/>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<ol style='list-style-position:inside;'>
|
||||||
|
<li>First item</li>
|
||||||
|
<li>Second item</li>
|
||||||
|
<li>Third item</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<h3>Unordered List</h3>
|
||||||
|
|
||||||
|
"- First item"<br/>
|
||||||
|
"- Second item"<br/>
|
||||||
|
"- Third item"<br/>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<ul style='list-style-position:inside;'>
|
||||||
|
<li>First item</li>
|
||||||
|
<li>Second item</li>
|
||||||
|
<li>Third item</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3>Code</h3>
|
||||||
|
|
||||||
|
"`code`"<br/>
|
||||||
|
|
||||||
|
<code>code</code><br/>
|
||||||
|
|
||||||
|
<h3>Horizontal Rule</h3>
|
||||||
|
|
||||||
|
"---"<br/>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<h3>Link</h3>
|
||||||
|
|
||||||
|
"[Markdown Guide](https://www.markdownguide.org)"<br/>
|
||||||
|
|
||||||
|
<a href='//www.markdownguide.org'>Markdown Guide</a><br/>
|
||||||
|
|
||||||
|
<h3>Image</h3>
|
||||||
|
|
||||||
|
"![alt text](https://www.markdownguide.org/assets/images/tux.png)"<br/>
|
||||||
|
|
||||||
|
<img src='//www.markdownguide.org/assets/images/tux.png' alt='alt text' /><br/>
|
||||||
|
|
||||||
|
<h2>Extended Syntax</h2>
|
||||||
|
|
||||||
|
<p>These elements extend the basic syntax by adding additional features. Not all Markdown applications support these elements.</p>
|
||||||
|
|
||||||
|
<h3>Table</h3>
|
||||||
|
|
||||||
|
| Syntax | Description |<br/>
|
||||||
|
| ----------- | ----------- |<br/>
|
||||||
|
| Header | Title |<br/>
|
||||||
|
| Paragraph | Text |<br/>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<th>Syntax</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Header</td>
|
||||||
|
<td>Title</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Paragraph</td>
|
||||||
|
<td>Text</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h3>Fenced Code Block</h3>
|
||||||
|
|
||||||
|
<p>Specifying the language after the first 3 backticks may help with text formatting and highlighting based on the language entered, may or may not be supported in a given Markdown tools implementation</p>
|
||||||
|
|
||||||
|
```json<br/>
|
||||||
|
{<br/>
|
||||||
|
"firstName": "John",<br/>
|
||||||
|
"lastName": "Smith",<br/>
|
||||||
|
"age": 25,<br/>
|
||||||
|
}<br/>
|
||||||
|
```<br/>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
{
|
||||||
|
"firstName": "John",
|
||||||
|
"lastName": "Smith",
|
||||||
|
"age": 25
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
@ -7,17 +7,35 @@
|
|||||||
<link href='/theme/assets/css/jquery-ui.theme.css' rel='stylesheet' />
|
<link href='/theme/assets/css/jquery-ui.theme.css' rel='stylesheet' />
|
||||||
<link href='/theme/assets/css/jquery-ui.structure.css' rel='stylesheet' />
|
<link href='/theme/assets/css/jquery-ui.structure.css' rel='stylesheet' />
|
||||||
<link href='/css/style.css' rel='stylesheet' />
|
<link href='/css/style.css' rel='stylesheet' />
|
||||||
|
<link href='//cdn.datatables.net/2.0.8/css/dataTables.dataTables.min.css' rel='stylesheet' />
|
||||||
|
<style>
|
||||||
|
#notes,
|
||||||
|
#notePreview {
|
||||||
|
font-size: {{ meta.noteTextSize }}pt;
|
||||||
|
}
|
||||||
|
button.button i {
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block javascripts %}
|
{% block javascripts %}
|
||||||
<script src='/js/script.js'></script>
|
|
||||||
<script src="/theme/assets/js/jquery.min.js"></script>
|
<script src="/theme/assets/js/jquery.min.js"></script>
|
||||||
<script src='/theme/assets/js/jquery-ui.js'></script>
|
<script src='/theme/assets/js/jquery-ui.js'></script>
|
||||||
<script src="/theme/assets/js/browser.min.js"></script>
|
<script src="/theme/assets/js/browser.min.js"></script>
|
||||||
<script src="/theme/assets/js/breakpoints.min.js"></script>
|
<script src="/theme/assets/js/breakpoints.min.js"></script>
|
||||||
<script src="/theme/assets/js/util.js"></script>
|
<script src="/theme/assets/js/util.js"></script>
|
||||||
<script src="/theme/assets/js/main.js"></script>
|
<script src="/theme/assets/js/main.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/markdown-it/13.0.2/markdown-it.min.js" integrity="sha512-ohlWmsCxOu0bph1om5eDL0jm/83eH09fvqLDhiEdiqfDeJbEvz4FSbeY0gLJSVJwQAp0laRhTXbUQG+ZUuifUQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
<script src='//momentjs.com/downloads/moment-with-locales.js'></script>
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/markdown-it/13.0.2/markdown-it.min.js" integrity="sha512-ohlWmsCxOu0bph1om5eDL0jm/83eH09fvqLDhiEdiqfDeJbEvz4FSbeY0gLJSVJwQAp0laRhTXbUQG+ZUuifUQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
|
<script src='//cdn.datatables.net/2.0.8/js/dataTables.min.js'></script>
|
||||||
|
<script>
|
||||||
|
let saveInterval = ({{ meta.saveInterval }} * 1000);
|
||||||
|
let saveTimeout = ({{ meta.saveTimeout }} * 1000);
|
||||||
|
const SAVE_FAILURE_LIMIT = {{ meta.saveFailureCount }};
|
||||||
|
let saveFailureCount = {{ meta.saveFailureCount }};
|
||||||
|
</script>
|
||||||
|
<script src='/js/script.js'></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
@ -34,11 +52,11 @@
|
|||||||
<div style='display:inline-block'>
|
<div style='display:inline-block'>
|
||||||
<button onclick='increaseFont()'><i class='fa fa-plus'></i></button>
|
<button onclick='increaseFont()'><i class='fa fa-plus'></i></button>
|
||||||
<button onclick='decreaseFont()'><i class='fa fa-minus'></i></button>
|
<button onclick='decreaseFont()'><i class='fa fa-minus'></i></button>
|
||||||
<button onclick='openRef(false)'><i class='fa fa-book'></i></button>
|
<button id='openRefBtn' class='button' onclick='openRef(false)'><i class='fa fa-book'></i></button>
|
||||||
</div>
|
</div>
|
||||||
<div id="ref" style='font-size:12pt;'></div>
|
<div id="ref" style='font-size:12pt;'></div>
|
||||||
<div id='note-list'>
|
<div id='note-list'>
|
||||||
<table>
|
<table id='note-table' data-order='[[ 3, "desc" ]]'>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Title</th>
|
<th>Title</th>
|
||||||
@ -47,11 +65,6 @@
|
|||||||
<th>Date</th>
|
<th>Date</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
|
||||||
{% for n in reverseNoteSort %}
|
|
||||||
{{ n.toTableRow()|raw }}
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@ -59,10 +72,10 @@
|
|||||||
<section class="notes">
|
<section class="notes">
|
||||||
<div id='note-header-left'>
|
<div id='note-header-left'>
|
||||||
<h2>Notes</h2>
|
<h2>Notes</h2>
|
||||||
<i id='save-check' class='fa fa-check'></i>
|
<i id='save-check' class='fa fa-save'></i>
|
||||||
</div>
|
</div>
|
||||||
<div id='note-header-right'>
|
<div id='note-header-right'>
|
||||||
<select id='template' onchange="retrieveTemplate('template','notes')">
|
<select id='template' onchange="retrieveTemplate('template','notes')" style='width:200px;'>
|
||||||
<option value=0>-- Template --</option>
|
<option value=0>-- Template --</option>
|
||||||
{% for t in app.user.templates %}
|
{% for t in app.user.templates %}
|
||||||
<option value="{{ t.id }}">{{ t.name }}</option>
|
<option value="{{ t.id }}">{{ t.name }}</option>
|
||||||
@ -70,17 +83,22 @@
|
|||||||
</select>
|
</select>
|
||||||
<button id="previewBtn" class='button' onclick='previewNote()'>
|
<button id="previewBtn" class='button' onclick='previewNote()'>
|
||||||
<i class='fa fa-eye'></i>
|
<i class='fa fa-eye'></i>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button id='show-hide-btn' class='button' onclick='toggleFields()'>
|
<button id='show-hide-btn' class='button' onclick='toggleFields()'>
|
||||||
<i class='fa fa-table'></i>
|
<i class='fa fa-table'></i>
|
||||||
|
</button>
|
||||||
|
<button id='shareBtn' class='button'>
|
||||||
|
<i class='fas fa-share-alt'></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id='fields-container'>
|
<div id='fields-container'>
|
||||||
<input type="hidden" id="noteId" value="" />
|
<input type="hidden" id="noteId" value="" />
|
||||||
<input type="text" id="noteTitle" placeholder="Title..." />
|
<input type="text" id="noteTitle" placeholder="Title..." />
|
||||||
<input type='text' id='noteDate' onchange='textDirty=true;saved=false;' />
|
<input type='text' id='noteDate' placeholder='Date...' onchange='textDirty=true;saved=false;' />
|
||||||
|
<input type='text' id='passage' placeholder='Passage...' onchange='saved=false;textDirty=true;' />
|
||||||
|
<br />
|
||||||
|
<input type='text' id='recording' name='recording' placeholder='Recording link...' />
|
||||||
<input type='text' id='newSpeaker' placeholder='Name...' onkeyup='saveSpeaker(event)' style='display:none;' />
|
<input type='text' id='newSpeaker' placeholder='Name...' onkeyup='saveSpeaker(event)' style='display:none;' />
|
||||||
<select id="speaker" onchange='newSpeaker()'>
|
<select id="speaker" onchange='newSpeaker()'>
|
||||||
<option value=0>-- Speaker --</option>
|
<option value=0>-- Speaker --</option>
|
||||||
@ -97,7 +115,6 @@
|
|||||||
<option value='{{ s.id }}'>{{ s.name }}</option>
|
<option value='{{ s.id }}'>{{ s.name }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
<input type='text' id='passage' placeholder='Passage...' onchange='saved=false;textDirty=true;' />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<textarea id="notes" wrap="hard"></textarea>
|
<textarea id="notes" wrap="hard"></textarea>
|
||||||
@ -121,6 +138,12 @@
|
|||||||
<option value='wcf'>Westminster Confession of Faith</option>
|
<option value='wcf'>Westminster Confession of Faith</option>
|
||||||
<option value='wsc'>Westminster Shorter Catechism</option>
|
<option value='wsc'>Westminster Shorter Catechism</option>
|
||||||
<option value='wlc'>Westminster Larger Catechism</option>
|
<option value='wlc'>Westminster Larger Catechism</option>
|
||||||
|
<option value='lbc'>London Baptist Confession</option>
|
||||||
|
<option value='39a'>Thirty-Nine Articles</option>
|
||||||
|
<option value='1hc'>First Helvetic Confession</option>
|
||||||
|
<option value='2hc'>Second Helvetic Confession</option>
|
||||||
|
<option value='sd'>Savoy Declaration</option>
|
||||||
|
<option value='agc'>Augsburg Confession</option>
|
||||||
</select>
|
</select>
|
||||||
<select id='referenceBook' onchange='filterBooks()'>
|
<select id='referenceBook' onchange='filterBooks()'>
|
||||||
</select>
|
</select>
|
||||||
@ -134,4 +157,25 @@
|
|||||||
|
|
||||||
<div id='passage-popup'>
|
<div id='passage-popup'>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- The modal background -->
|
||||||
|
<div id='modal-backdrop' class="modal-backdrop fade in" style='display:none;'></div>
|
||||||
|
|
||||||
|
<!-- The modal container -->
|
||||||
|
<div id='modal-container' class="modal-container" style='display:none;'>
|
||||||
|
<!-- The modal header -->
|
||||||
|
<header class="modal-header">Share Note</header>
|
||||||
|
|
||||||
|
<!-- The modal body -->
|
||||||
|
<form id="emailForm" class="modal-body">
|
||||||
|
<label for="email">Enter Friends Email:</label>
|
||||||
|
<input type="email" id="shareEmail" name="email" required />
|
||||||
|
<button type='button' id="submit" class="btn btn-primary" onclick='shareNote()'>Submit</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<!-- The modal footer -->
|
||||||
|
<footer class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal" onclick='closeShareNote()'>Close</button>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
185
templates/default/profile.html.twig
Normal file
185
templates/default/profile.html.twig
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
{% extends 'base.html.twig' %}
|
||||||
|
|
||||||
|
{% block title %}Profile | Sermon Notes{% endblock %}
|
||||||
|
|
||||||
|
{% block stylesheets %}
|
||||||
|
<link href="/theme/assets/css/main.css" rel="stylesheet" />
|
||||||
|
<link href='/theme/assets/css/jquery-ui.theme.css' rel='stylesheet' />
|
||||||
|
<link href='/theme/assets/css/jquery-ui.structure.css' rel='stylesheet' />
|
||||||
|
<link href='/css/style.css' rel='stylesheet' />
|
||||||
|
<link href='//cdn.datatables.net/2.0.8/css/dataTables.dataTables.min.css' rel='stylesheet' />
|
||||||
|
<style>
|
||||||
|
.flex-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
justify-content: normal;
|
||||||
|
align-items: normal;
|
||||||
|
align-content: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-flex {
|
||||||
|
display: block;
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-shrink: 1;
|
||||||
|
flex-basis: auto;
|
||||||
|
align-self: auto;
|
||||||
|
order: 0;
|
||||||
|
border: solid 1px black;
|
||||||
|
margin: 0 10px 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-flex {
|
||||||
|
display: block;
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-shrink: 1;
|
||||||
|
flex-basis: auto;
|
||||||
|
align-self: auto;
|
||||||
|
order: 0;
|
||||||
|
border: solid 1px black;
|
||||||
|
margin: 0 20px 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notes-flex {
|
||||||
|
display: block;
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 1;
|
||||||
|
flex-basis: auto;
|
||||||
|
align-self: auto;
|
||||||
|
order: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
label,
|
||||||
|
input[type="number"],
|
||||||
|
input[type="email"],
|
||||||
|
input[type="text"] {
|
||||||
|
display: inline !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="checkbox"] {
|
||||||
|
appearance: auto;
|
||||||
|
opacity: 1;
|
||||||
|
margin: 0;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block javascripts %}
|
||||||
|
<script src="/theme/assets/js/jquery.min.js"></script>
|
||||||
|
<script src='/theme/assets/js/jquery-ui.js'></script>
|
||||||
|
<script src="/theme/assets/js/browser.min.js"></script>
|
||||||
|
<script src="/theme/assets/js/breakpoints.min.js"></script>
|
||||||
|
<script src="/theme/assets/js/util.js"></script>
|
||||||
|
<script src="/theme/assets/js/main.js"></script>
|
||||||
|
<script src='//momentjs.com/downloads/moment-with-locales.js'></script>
|
||||||
|
<script src='//cdn.datatables.net/2.0.8/js/dataTables.min.js'></script>
|
||||||
|
<script type='text/javascript'>
|
||||||
|
$(function() {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
function saveSettings() {
|
||||||
|
var saveInterval = $('#save-interval');
|
||||||
|
var saveReferences = $('#save-references');
|
||||||
|
var noteTextSize = $('#note-text-size');
|
||||||
|
var trackSaveSize = $('#track-save-size');
|
||||||
|
var saveTimeout = $('#save-timeout');
|
||||||
|
var saveFailureCount = $('#save-failure-count');
|
||||||
|
|
||||||
|
fetch('/index.php/save-settings', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
'saveInterval': saveInterval.val(),
|
||||||
|
'saveReferences': saveReferences.is(':checked'),
|
||||||
|
'noteTextSize': noteTextSize.val(),
|
||||||
|
'trackSaveSize': trackSaveSize.is(':checked'),
|
||||||
|
'saveTimeout': saveTimeout.val(),
|
||||||
|
'saveFailureCount': saveFailureCount.val()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(results => {
|
||||||
|
alert(results.msg);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<div class="flex-container">
|
||||||
|
<div class="user-flex">
|
||||||
|
<label for='name'>Name: </label>
|
||||||
|
<input type='text' id='name' name='name' value='{{ app.user.name }}' /><br />
|
||||||
|
|
||||||
|
<label for='email'>Email: </label>
|
||||||
|
<input type='email' id='email' name='email' value='{{ app.user.email }}' /><br />
|
||||||
|
|
||||||
|
<label for='password'>Password: </label>
|
||||||
|
<input type='password' id='password' name='password' /><br/>
|
||||||
|
|
||||||
|
<label for='new-password'>New Password: </label>
|
||||||
|
<input type='password' id='new-password' name='new-password' /><br />
|
||||||
|
|
||||||
|
<label for='conf-password'>Confirm Password: </label>
|
||||||
|
<input type='password' id='conf-password' name='conf-password' /><br />
|
||||||
|
|
||||||
|
<button id='save-profile' onclick='saveProfile()'>Save Profile</button>
|
||||||
|
</div>
|
||||||
|
<div class="settings-flex">
|
||||||
|
<label for='save-interval'>Save Interval (seconds)?</label>
|
||||||
|
<input type='number' id='save-interval' value='{{ meta.saveInterval }}' title='What is the interval to trigger an autosave, in seconds?' /><br/>
|
||||||
|
|
||||||
|
<label for='save-references'>Save References?</label>
|
||||||
|
<input type='checkbox' id='save-references' {{ meta.saveReferences }} title='Do you want to also save reference content' /><br />
|
||||||
|
|
||||||
|
<label for='note-text-size'>Note Text Size? (points)</label>
|
||||||
|
<input type='number' id='note-text-size' value='{{ meta.noteTextSize }}' title='Font size of the note preview, in points' /><br />
|
||||||
|
|
||||||
|
<label for='track-save-size'>Track Save Size?</label>
|
||||||
|
<input type='checkbox' id='track-save-size' {{ meta.noteTextSize }} title='Do you want to track the size of saves, useful if teathering to mobile device?' /><br />
|
||||||
|
|
||||||
|
<label for='save-timeout'>Save Timeout? (seconds)</label>
|
||||||
|
<input type='number' id='save-timeout' value='{{ meta.saveTimeout }}' title='How long does it wait to before cancelling the save and trying again later?' /><br />
|
||||||
|
|
||||||
|
<label for='save-failure-count'>Save Failure Count? </label>
|
||||||
|
<input type='number' id='save-failure-count' value='{{ meta.saveFailureCount }}' title='How many times do you want to attempt to auto save before it stops and waits for a manual attempt' /><br />
|
||||||
|
|
||||||
|
<button id='save-settings' onclick='saveSettings()'>Save Settings</button>
|
||||||
|
<button id='back' onclick='history.go(-1)'>Back</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='flex-container'>
|
||||||
|
<div class='user-flex'>
|
||||||
|
<h2>My Shared Notes</h2>
|
||||||
|
<table id='shared-notes'>
|
||||||
|
<thead>
|
||||||
|
<th>Recipient</th>
|
||||||
|
<th>Title</th>
|
||||||
|
<th>Passage</th>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='settings-flex'>'
|
||||||
|
<h2>Notes Shared w/Me</h2>
|
||||||
|
|
||||||
|
<table id='shared-with-me'>
|
||||||
|
<thead>
|
||||||
|
<th>Owner</th>
|
||||||
|
<th>Title</th>
|
||||||
|
<th>Passage</th>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
@ -13,7 +13,7 @@
|
|||||||
<nav id="menu">
|
<nav id="menu">
|
||||||
<header class="major">
|
<header class="major">
|
||||||
{% if app.user %}
|
{% if app.user %}
|
||||||
<h3>Welcome {{ app.user.name }}</h3>
|
<h3>Welcome <a href='/index.php/profile' style='text-decoration:underline;'>{{ app.user.name }}</a></h3>
|
||||||
<a href='/index.php/logout'>Logout</a>
|
<a href='/index.php/logout'>Logout</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</header>
|
</header>
|
||||||
@ -29,6 +29,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
<li><a href='#' onclick="openRef()">Open Reference</a></li>
|
<li><a href='#' onclick="openRef()">Open Reference</a></li>
|
||||||
<li><a href='/index.php/template-editor'>Template Editor</a></li>
|
<li><a href='/index.php/template-editor'>Template Editor</a></li>
|
||||||
|
<li><a href='/index.php/cheat-sheet' target='_blank'>Markdown Cheat Sheet</a></li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<li><a href="/index.php/">Home</a></li>
|
<li><a href="/index.php/">Home</a></li>
|
||||||
<li><a href='/index.php/register'>Register</a></li>
|
<li><a href='/index.php/register'>Register</a></li>
|
||||||
|
@ -5,44 +5,26 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<select id='references' onchange='retrieveReference(this)'>
|
<select id='referenceTypes' onchange='retrieveReferenceType(this)'>
|
||||||
<option value=''>-- Select Reference --</option>
|
<option value=''>-- Select Reference --</option>
|
||||||
<optgroup id='creeds' label='Creeds'>
|
<option value='new'>-- Insert New --</option>
|
||||||
{% for c in creeds %}
|
<option value='creed'>Creed</option>
|
||||||
<option type='creed'>{{ c }}</option>
|
<option value='belgic'>Belgic Confession</option>
|
||||||
{% endfor %}
|
<option value='hc'>Heidelberg Catechism</option>
|
||||||
</optgroup>
|
<option value='cd'>Canons of Dort</option>
|
||||||
<optgroup id='belgic' label='Belgic Confession'>
|
<option value='wcf'>Westminster Confession of Faith</option>
|
||||||
{% for c in belgic %}
|
<option value='wsc'>Westminster Shorter Catechism</option>
|
||||||
<option type='bc'>{{ c }}</option>
|
<option value='wlc'>Westminster Larger Catechism</option>
|
||||||
{% endfor %}
|
<option value='agc'>Augsberg Confession</option>
|
||||||
</optgroup>
|
<option value='1hc'>First Helvetic Confession</option>
|
||||||
<optgroup id='heidelberg' label='Heidelberg Catechism'>
|
<option value='2hc'>Second Helvetic Confession</option>
|
||||||
{% for c in heidelberg %}
|
<option value='sd'>Savoy Declaration</option>
|
||||||
<option type='hc'>{{ c }}</option>
|
<option value='39a'>Thirty-Nine Articles</option>
|
||||||
{% endfor %}
|
<option value='lbc'>London Baptist Confession</option>
|
||||||
</optgroup>
|
</select>
|
||||||
<optgroup id='dort' label='Canons of Dort'>
|
<select id='referenceSeries' onchange='retrieveReference(this)'>
|
||||||
{% for c in dort %}
|
</select>
|
||||||
<option type='cd'>{{ c }}</option>
|
<input type='text' name='name' id='refName' style='display:none;' />
|
||||||
{% endfor %}
|
|
||||||
</optgroup>
|
|
||||||
<optgroup id='wcf' label='Westminster Confession of Faith'>
|
|
||||||
{% for c in wcf %}
|
|
||||||
<option type='wcf'>{{ c }}</option>
|
|
||||||
{% endfor %}
|
|
||||||
</optgroup>
|
|
||||||
<optgroup id='wsc' label='Westminster Short Catechism'>
|
|
||||||
{% for c in wsc %}
|
|
||||||
<option type='wsc'>{{ c }}</option>
|
|
||||||
{% endfor %}
|
|
||||||
</optgroup>
|
|
||||||
<optgroup id='wlc' label='Westminster Larger Catechism'>
|
|
||||||
{% for c in wlc %}
|
|
||||||
<option type='wlc'>{{ c }}</option>
|
|
||||||
{% endfor %}
|
|
||||||
</optgroup>
|
|
||||||
</select>
|
|
||||||
<button id='save' name='save' onclick='saveReference()'>Save</button>
|
<button id='save' name='save' onclick='saveReference()'>Save</button>
|
||||||
<a href='/index.php/home'>Back</a><br />
|
<a href='/index.php/home'>Back</a><br />
|
||||||
|
|
||||||
|
24
templates/emails/note-shared.html.twig
Normal file
24
templates/emails/note-shared.html.twig
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
{{ owner.name }} has shared a note with you, what follows are their formatted notes.
|
||||||
|
{% if isRegistered %}
|
||||||
|
You can see shared notes <a href='{{ domain }}/index.php/shared-notes'>here</a>.
|
||||||
|
{% else %}
|
||||||
|
You can register for an account <a href='{{ domain }}/index.php/register'>here</a>, or just review the notes below
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
||||||
|
<h1>{{ note.title }}</h1>
|
||||||
|
<blockquote>
|
||||||
|
Passage: {{ note.passage }}<br/>
|
||||||
|
Date: {{ note.date | date("F j Y") }}<br/>
|
||||||
|
Speaker: {{ note.speaker.name }}<br/>
|
||||||
|
Series: {{ note.series.name }}<br/>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
{{ formattedText | raw }}
|
||||||
|
</body>
|
||||||
|
</html>
|
9
templates/emails/registration.html.twig
Normal file
9
templates/emails/registration.html.twig
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head></head>
|
||||||
|
<body>
|
||||||
|
<h1>New User Registered</h1>
|
||||||
|
Name: {{ user.name }}<br />
|
||||||
|
Email: {{ user.email }}
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user