Compare commits
32 Commits
1.0
...
fba8454743
Author | SHA1 | Date | |
---|---|---|---|
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 | |||
11f566897f | |||
7044d16ee0 |
@ -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
|
@ -4,7 +4,9 @@ A program to take notes during a sermon. The web app was built with PHP and Sym
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
The best option for installing is using the Docker container. Download the `docker-compose.yml` file from this repository and run `docker-compose up -d` from the command line.
|
1. Run `docker run -d --name sermon-notes -p 80:80 ryanprather/sermon-notes:latest`, this will download and start the container and keep it running in the background. If you already have something on port 80 change the first `80` to whatever open port you'd like.
|
||||||
|
2. Run `docker exec -it sermon-notes bash install.sh` This will run an install script to create an .env file specific to your install, populate with the beginning factors, and then run a `composer` command to download the necessary package dependancies.
|
||||||
|
3. Once complete you have a running system that you can navigate to in your browser with `http://{ip}:{port}|{hostname}:{port}`. Then you just need to register for an account. The first account that is created is made an admin so that you can access the `Reference Editor` and update any reference material if necessary.
|
||||||
|
|
||||||
## Operation
|
## Operation
|
||||||
|
|
||||||
@ -24,7 +26,7 @@ Once you get logged in you'll be presented with the main home page
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
If you are accessing on a regular iPad the menu should be collapsed, if not, you may need to do that. I built this with a iPad 9th Gen in mind so your mileage may vary.
|
If you are accessing on a regular iPad the menu should be collapsed, if not, you may need to do that. I built this with a iPad 9th Gen in mind so visibility on another device may vary.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@ -62,5 +64,5 @@ or if the note was recently made you will see the most recent 4 notes listed und
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
By click either of the title links it will open the note and display it for you to edit or read. I can add "Notes" as future reference content.
|
By clicking either of the title links it will open the note and display it for you to edit or read. I can add "Notes" as future reference content.
|
||||||
|
|
||||||
|
BIN
data/data.db
BIN
data/data.db
Binary file not shown.
@ -4,10 +4,7 @@ services:
|
|||||||
sermon-notes:
|
sermon-notes:
|
||||||
container_name: sermon-notes
|
container_name: sermon-notes
|
||||||
image: ryanprather/sermon-notes:latest
|
image: ryanprather/sermon-notes:latest
|
||||||
command:
|
|
||||||
- "php bin/console doctrine:migrations:migrate --no-interaction"
|
|
||||||
- "bash install.sh"
|
|
||||||
ports:
|
ports:
|
||||||
- 80:80
|
- 80:80
|
||||||
volumes:
|
volumes:
|
||||||
- .:/var/www/html
|
- ./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)');
|
||||||
|
}
|
||||||
|
}
|
@ -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,17 @@ 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;
|
||||||
}/*# 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","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: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;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}/*# 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","file":"style.min.css"}
|
@ -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,17 @@ 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;
|
||||||
|
}
|
@ -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,12 +4,36 @@ var references = {};
|
|||||||
var tabs = [];
|
var tabs = [];
|
||||||
let saved = false;
|
let saved = false;
|
||||||
let textDirty = false;
|
let textDirty = false;
|
||||||
let saveTimeout = 10000;
|
let saveTimeout = 15000;
|
||||||
var to = null;
|
var to = null;
|
||||||
let controller;
|
let controller;
|
||||||
var BOOKS = {};
|
var BOOKS = {};
|
||||||
|
let saveFailCounter = 0;
|
||||||
|
|
||||||
fetch('/js/data.json')
|
$(function () {
|
||||||
|
setHeight();
|
||||||
|
setBooks();
|
||||||
|
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")
|
||||||
|
},
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function setBooks() {
|
||||||
|
fetch('/js/data.json')
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
throw new Error('HTTP Error: Status: ${res.status}');
|
throw new Error('HTTP Error: Status: ${res.status}');
|
||||||
@ -22,21 +46,24 @@ fetch('/js/data.json')
|
|||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
document.addEventListener('keyup', function (event) {
|
function setEventListeners() {
|
||||||
|
document.addEventListener('keyup', function (event) {
|
||||||
if (event.key == "F3") {
|
if (event.key == "F3") {
|
||||||
openRef(false);
|
openRef(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
document.querySelector('#notes').addEventListener('keyup', function (event) {
|
document.querySelector('#notes').addEventListener('keyup', function (event) {
|
||||||
let key = event.keyCode;
|
let key = event.keyCode;
|
||||||
|
|
||||||
if (key >= 48 && key <= 90 || key >= 96 && key <= 111 || key >= 186 && key <= 222) {
|
if (key >= 48 && key <= 90 || key >= 96 && key <= 111 || key >= 186 && key <= 222) {
|
||||||
textDirty = true;
|
textDirty = true;
|
||||||
document.querySelector('#note-header-left h2').classList.add('dirty');
|
document.querySelector('#note-header-left h2').classList.add('dirty');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function setHeight() {
|
function setHeight() {
|
||||||
md = new markdownit({
|
md = new markdownit({
|
||||||
@ -133,7 +160,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 = '';
|
||||||
@ -158,6 +186,7 @@ function saveNote(event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let saveCheck = document.querySelector('#save-check');
|
let saveCheck = document.querySelector('#save-check');
|
||||||
|
var noteText = document.querySelector('#notes').value;
|
||||||
|
|
||||||
startSave();
|
startSave();
|
||||||
|
|
||||||
@ -169,6 +198,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({
|
||||||
@ -181,29 +211,36 @@ function saveNote(event) {
|
|||||||
})
|
})
|
||||||
.done(function (data) {
|
.done(function (data) {
|
||||||
if (data.msg == 'saved' && !saved) {
|
if (data.msg == 'saved' && !saved) {
|
||||||
saveCheck.classList.remove('saving');
|
saveCheck.classList.remove('saving', 'error', 'fa-times', 'fa-check');
|
||||||
showSave();
|
showSave();
|
||||||
|
if (noteText == document.querySelector('#notes').value) {
|
||||||
saved = true;
|
saved = true;
|
||||||
textDirty = false;
|
textDirty = false;
|
||||||
document.querySelector('#note-header-left h2').classList.remove('dirty');
|
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');
|
saveFailCounter++;
|
||||||
saveCheck.classList.add('error');
|
saveCheck.classList.remove('saving', 'fa-check');
|
||||||
console.error(data);
|
saveCheck.classList.add('fa-times', '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-check');
|
||||||
saveCheck.classList.add('error');
|
saveCheck.classList.add('error', 'fa-times');
|
||||||
}
|
}
|
||||||
clearTimeout(to);
|
clearTimeout(to);
|
||||||
|
if (saveFailCounter < 5) {
|
||||||
to = setTimeout(saveNote, saveTimeout);
|
to = setTimeout(saveNote, saveTimeout);
|
||||||
|
} else {
|
||||||
|
saveFailCounter = 0;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,7 +268,8 @@ function isUuidValid(uuid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function startSave() {
|
function startSave() {
|
||||||
document.querySelector('#save-check').classList.add('saving');
|
document.querySelector('#save-check').classList.remove('error', 'fa-times', 'fa-check');
|
||||||
|
document.querySelector('#save-check').classList.add('saving', 'fa-check');
|
||||||
document.querySelector('#save-check').style.opacity = 1;
|
document.querySelector('#save-check').style.opacity = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,6 +283,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-check');
|
||||||
|
|
||||||
// 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 () {
|
||||||
@ -271,6 +310,9 @@ function discardNote() {
|
|||||||
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', {
|
fetch('/index.php/discard-note', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -368,6 +410,8 @@ function saveSeries(event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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';
|
||||||
|
|
||||||
@ -389,6 +433,7 @@ 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');
|
||||||
}
|
}
|
||||||
|
|
||||||
function queryRef(type = null, book = null, input = null) {
|
function queryRef(type = null, book = null, input = null) {
|
||||||
@ -438,10 +483,11 @@ function queryRef(type = null, book = null, input = null) {
|
|||||||
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,16 +502,16 @@ function makeButton(title) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
removeActiveRef();
|
removeActiveRef();
|
||||||
btn.classList.add('activeRef');
|
btn.classList.add('active');
|
||||||
|
|
||||||
return btn;
|
return btn;
|
||||||
}
|
}
|
||||||
|
|
||||||
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');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -573,6 +619,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];
|
||||||
@ -622,15 +692,42 @@ function filterVerse() {
|
|||||||
verseRange.innerText = 'Verse: ' + verse;
|
verseRange.innerText = 'Verse: ' + verse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
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())
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,6 +166,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 +176,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 +203,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 +225,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 +258,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 +293,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 +316,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);
|
||||||
|
@ -18,6 +18,9 @@ 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');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,28 +38,18 @@ class DefaultController extends AbstractController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[Route('/cheat-sheet', name: 'app_cheat_sheet')]
|
||||||
|
public function cheatSheet(): Response
|
||||||
|
{
|
||||||
|
return $this->render('default/cheat-sheet.html.twig');
|
||||||
|
}
|
||||||
|
|
||||||
#[Route('/reference-editor', name: 'app_reference_editor')]
|
#[Route('/reference-editor', name: 'app_reference_editor')]
|
||||||
public function referenceEditor(EntityManagerInterface $emi): Response
|
public function referenceEditor(EntityManagerInterface $emi): Response
|
||||||
{
|
{
|
||||||
$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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,7 +169,13 @@ class Note implements JsonSerializable
|
|||||||
{
|
{
|
||||||
return "<a href='#' onclick=\"retrieveNote('{$this->id}')\">".
|
return "<a href='#' onclick=\"retrieveNote('{$this->id}')\">".
|
||||||
$this->title.
|
$this->title.
|
||||||
"</a>";
|
"</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
|
||||||
@ -183,6 +192,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 +203,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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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>
|
||||||
|
|
||||||
|
""<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,20 @@
|
|||||||
<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' />
|
||||||
{% 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 src='/js/script.js'></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
@ -34,11 +37,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 +50,11 @@
|
|||||||
<th>Date</th>
|
<th>Date</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
{#<tbody>
|
||||||
{% for n in reverseNoteSort %}
|
{% for n in reverseNoteSort %}
|
||||||
{{ n.toTableRow()|raw }}
|
{{ n.toTableRow()|raw }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>#}
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@ -80,7 +83,10 @@
|
|||||||
<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 +103,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 +126,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>
|
||||||
|
@ -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 />
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user