Initial commit of content.

This commit is contained in:
2021-01-13 11:25:45 -08:00
commit 9b8760fd34
67 changed files with 25486 additions and 0 deletions

19
.gitignore vendored Normal file
View File

@@ -0,0 +1,19 @@
/locales
npm-debug.log
/data
/public/uploads
/public/apos-minified
/data/temp/uploadfs
node_modules
# This folder is created on the fly and contains symlinks updated at startup (we'll come up with a Windows solution that actually copies things)
/public/modules
# We don't commit CSS, only LESS
/public/css/*.css
/public/css/*.map
# Don't commit masters generated on the fly at startup, these import all the rest
/public/css/master-*.less
.jshintrc
/public/js/_site-compiled.js
# Don't include the .idea folder which is used by the Webstorm IDE
.idea/workspace.xml
.idea/

7
Dockerfile Normal file
View File

@@ -0,0 +1,7 @@
FROM node:current
WORKDIR /app
COPY package.json /app
RUN npm install
COPY . /app
EXPOSE 3000
CMD [ "./scripts/wait-for-it.sh", "mongo:27017", "--", "npm", "start" ]

7
LICENSE Normal file
View File

@@ -0,0 +1,7 @@
Copyright (c) 2020 Apostrophe, Technologies, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

54
README.md Normal file
View File

@@ -0,0 +1,54 @@
# Apostrophe Boilerplate v2.x
Apostrophe Boilerplate is a minimal starting point for [Apostrophe 2](https://github.com/apostrophecms/apostrophe) projects.
To get started, we recommend taking a look at [our guide to creating your first project](http://apostrophecms.org/docs/tutorials/getting-started/creating-your-first-project.html). You could also take a look at [Apostrophe's CLI](https://github.com/apostrophecms/apostrophe) or simply fork this repository.
Once you have a local copy of this project to work from, make sure to install its dependencies with `npm install`. With Apostrophe installed, the first thing to do create an admin user account so you're able to log into the CMS. Run the following command (this will prompt you for a password).
```bash
node app.js apostrophe-users:add admin admin
```
Now you're all set! Just run `node app.js` to start up the local server and head to `localhost:3000` in your web browser.
---------------
For more documentation on Apostrophe, visit the [A2 documentation site](http://apostrophecms.com).
## Getting started with Docker
If you prefer, you can run Apostrophe inside a Docker container with the provided configuration in `Dockerfile` and `docker-compose.yml`.
**These aren't meant to be perfect for all situations.** As written, they are well-suited to running Apostrophe and MongoDB under docker in a single-server environment. For a development environment, you would probably want the entire folder to be in a mounted volume so that your code changes are visible as you go along, and you would probably want to work `nodemon`, `webpack` or `apostrophe-monitor` into the mix for automatic reloading.
1. Install Docker on your computer, of course. On MacOS you must install the official Docker Desktop, not homebrew, as the latter relies on virtualbox and virtualbox file sharing is not compatible with persisting a MongoDB database in a container. If this is your first time, **Be sure to actually launch Docker Desktop** before running the commands that follow.
2. Type:
```bash
docker-compose up
```
3. When you see:
```
Listening at http://localhost:3000
```
You can connect normally in your browser by going to that address.
4. You will note there is no `admin` account in the database yet. Let's fix that. We'll execute an Apostrophe command line task inside the container:
```
docker-compose exec apostrophe node app apostrophe-users:add admin admin
```
You can shut Apostrophe down at any time with:
```bash
docker-compose stop
```
When you start it up again, your uploaded files and your database will still be there.

57
app.js Normal file
View File

@@ -0,0 +1,57 @@
var path = require('path');
var apos = require('apostrophe')({
// Export for apostrophe-monitor which manages restarting the apostrophe system (not the whole nodeJS process) when changes are made.
// See https://github.com/apostrophecms/apostrophe-monitor
root: module,
shortName: 'avusd',
// See lib/modules for basic project-level configuration of our modules
// responsible for serving static assets, managing page templates and
// configuring user accounts.
modules: {
'two-column-widgets': {extend: 'apostrophe-widgets'},
// Apostrophe module configuration
// Note: most configuration occurs in the respective
// modules' directories. See lib/apostrophe-assets/index.js for an example.
// However any modules that are not present by default in Apostrophe must at
// least have a minimal configuration here: `moduleName: {}`
// If a template is not found somewhere else, serve it from the top-level
// `views/` folder of the project
'apostrophe-templates': {viewsFolderFallback: path.join(__dirname, 'views')},
'apostrophe-express': {
'session': {
'secret': "ajg8zx734t6JS3nJxUJH5^9s34l12xci*JKDm wernDhqlL",
},
},
'apostrophe-assets': {
minify: (process.env.ENV === 'prod')
},
'apostrophe-db': {
uri: process.env.MONGO_URL
},
sanitizeHtml: {
allowedAttributes: {
'p': ['apos-indent1', 'apos-indent2']
},
allowedClasses: {
'p': ['apos-indent1', 'apos-indent2']
}
}
// Was having some issues with overlaying menus.
//'apostrophe-tiptap-rich-text-widgets': {}
}
});
// Export for apostrophe-monitor which manages restarting the apostrophe system (not the whole nodeJS process) when changes are made.
// See https://github.com/apostrophecms/apostrophe-monitor
module.exports = apos;

BIN
avusd_bundle.zip Normal file

Binary file not shown.

2
deployment/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
settings
settings.production

9
deployment/README Normal file
View File

@@ -0,0 +1,9 @@
This is a deployment folder for use with Stagecoach.
You don't have to use Stagecoach.
It's just a neat solution for deploying node apps.
See:
https://github.com/apostrophecms/stagecoach

48
deployment/dependencies Normal file
View File

@@ -0,0 +1,48 @@
#!/bin/bash
# Also a good place to ensure any data folders
# that are *not* supposed to be replaced on every deployment exist
# and create a symlink to them from the latest deployment directory.
# The real 'data' folder is shared. It lives two levels up and one over
# (we're in a deployment dir, which is a subdir of 'deployments', which
# is a subdir of the project's main dir)
HERE=`pwd`
mkdir -p ../data
ln -s ../data $HERE/data
# We also have a shared uploads folder which is convenient to keep
# in a separate place so we don't have to have two express.static calls
mkdir -p ../uploads
ln -s ../uploads $HERE/public/uploads
# Install any dependencies that can't just be rsynced over with
# the deployment. Example: node apps have npm modules in a
# node_modules folder. These may contain compiled C++ code that
# won't work portably from one server to another.
# This script runs after the rsync, but before the 'stop' script,
# so your app is not down during the npm installation.
# Make sure node_modules exists so npm doesn't go searching
# up the filesystem tree
mkdir -p node_modules
# If there is no package.json file then we don't need npm install
if [ -f './package.json' ]; then
# Install npm modules
# Use a suitable version of Python
# export PYTHON=/usr/bin/python26
npm install
if [ $? -ne 0 ]; then
echo "Error during npm install!"
exit 1
fi
fi
node app apostrophe-migrations:migrate --safe
# Generate new static asset files for this
# deployment of the app without shutting down
node app apostrophe:generation

8
deployment/migrate Normal file
View File

@@ -0,0 +1,8 @@
#!/bin/bash
# Run any necessary database migration tasks that should happen while the
# site is paused here.
node app apostrophe-migrations:migrate
echo "Site migrated"

View File

@@ -0,0 +1,14 @@
# List files and folders that shouldn't be deployed (such as data folders and runtime status files) here.
# In our projects .git and .gitignore are good candidates, also 'data' which contains persistent files
# that are *not* part of deployment. A good place for things like data/port, data/pid, and any
# sqlite databases or static web content you may need
data
temp
public/uploads
public/modules
public/apos-minified
.git
.gitignore
# We don't deploy these anymore, instead we always 'npm install' to ensure
# that any compiled C++ modules are built for the right architecture
node_modules

View File

@@ -0,0 +1,22 @@
#!/bin/bash
# Settings shared by all targets (staging, production, etc). Usually the
# shortname of the project (which is also the hostname for the frontend
# proxy server used for staging sites) and the directory name. For our
# web apps that use sc-proxy we make sure each is a subdirectory
# of /opt/stagecoach/apps
PROJECT=apostrophe
DIR=/opt/stagecoach/apps/$PROJECT
# Adjust the PATH environment variable on the remote host. Here's an example
# for deploying to MacPorts
#ADJUST_PATH='export PATH=/opt/local/bin:$PATH'
# ... But you probably won't need to on real servers. I just find it handy for
# testing parts of stagecoach locally on a Mac. : is an acceptable "no-op" (do-nothing) statement
ADJUST_PATH=':'
# ssh port. Sensible people leave this set to 22 but it's common to do the
# "security by obscurity" thing alas
SSH_PORT=22

View File

@@ -0,0 +1,10 @@
#!/bin/bash
# Settings specific to the 'master' deployment target.
# USER is the ssh user, SERVER is the ssh host. USER should
# match the USER setting in /opt/stagecoach/settings on
# the server
USER=myuser
SERVER=myserver.com

63
deployment/start Normal file
View File

@@ -0,0 +1,63 @@
#!/bin/bash
# Make the site live again, for instance by tweaking a .htaccess file
# or starting a node server. In this example we also set up a
# data/port file so that sc-proxy.js can figure out what port
# to forward traffic to for this site. The idea is that every
# folder in /var/webapps represents a separate project with a separate
# node process, each listening on a specific port, and they all
# need traffic forwarded from a reverse proxy server on port 80
# Useful for debugging
#set -x verbose
# Express should not reveal information on errors,
# also optimizes Express performance
export NODE_ENV=production
if [ ! -f "app.js" ]; then
echo "I don't see app.js in the current directory."
exit 1
fi
# Assign a port number if we don't yet have one
if [ -f "data/port" ]; then
PORT=`cat data/port`
else
# No port set yet for this site. Scan and sort the existing port numbers if any,
# grab the highest existing one
PORT=`cat ../../../*/data/port 2>/dev/null | sort -n | tail -1`
if [ "$PORT" == "" ]; then
echo "First app ever, assigning port 3000"
PORT=3000
else
# Bash is much nicer than sh! We can do math without tears!
let PORT+=1
fi
echo $PORT > data/port
echo "First startup, chose port $PORT for this site"
fi
# Run the app via 'forever' so that it restarts automatically if it fails
# Use `pwd` to make sure we have a full path, forever is otherwise easily confused
# and will stop every server with the same filename
# Use a "for" loop. A classic single-port file will do the
# right thing, but so will a file with multiple port numbers
# for load balancing across multiple cores
for port in $PORT
do
export PORT=$port
forever --minUptime=1000 --spinSleepTime=10000 -o data/console.log -e data/error.log start `pwd`/app.js && echo "Site started"
done
# Run the app without 'forever'. Record the process id so 'stop' can kill it later.
# We recommend installing 'forever' instead for node apps. For non-node apps this code
# may be helpful
#
# node app.js >> data/console.log 2>&1 &
# PID=$!
# echo $PID > data/pid
#
#echo "Site started"

27
deployment/stop Normal file
View File

@@ -0,0 +1,27 @@
#!/bin/bash
# Shut the site down, for instance by tweaking a .htaccess file to display
# a 'please wait' notice, or stopping a node server
if [ ! -f "app.js" ]; then
echo "I don't see app.js in the current directory."
exit 1
fi
# Stop the node app via 'forever'. You'll get a harmless warning if the app
# was not already running. Use `pwd` to make sure we have a full path,
# forever is otherwise easily confused and will stop every server with
# the same filename
forever stop `pwd`/app.js && echo "Site stopped"
# Stop the app without 'forever'. We recommend using 'forever' for node apps,
# but this may be your best bet for non-node apps
#
# if [ -f "data/pid" ]; then
# kill `cat data/pid`
# rm data/pid
# echo "Site stopped"
# else
# echo "Site was not running"
# fi

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 290 KiB

BIN
dev/images/AvLogo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1012 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 142 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 165 KiB

2
dev/images/avhsLogo.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 125 KiB

2
dev/images/avhsLogo2.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 122 KiB

BIN
dev/images/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
dev/images/panther.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

BIN
dev/images/panther.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 KiB

24
docker-compose.yml Normal file
View File

@@ -0,0 +1,24 @@
version: "2"
services:
apostrophe:
container_name: apostrophe
restart: always
build: .
ports:
- "3000:3000"
links:
- mongo
volumes:
- ./data/uploads:/app/public/uploads
environment:
- APOS_MONGODB_URI=mongodb://mongo:27017/db
depends_on:
- mongo
mongo:
container_name: mongo
image: mongo
restart: always
volumes:
- ./data/db:/data/db
expose:
- "27017"

View File

@@ -0,0 +1,20 @@
// This configures the apostrophe-assets module to push a 'site.less'
// stylesheet by default, and to use jQuery 3.x
module.exports = {
jQuery: 3,
stylesheets: [
{name: 'pre'},
{name: 'bootstrap'},
{name: 'main'},
{name: 'topBar'},
{name: 'menu'},
],
scripts: [
{name: 'bootstrap'},
{name: 'site'}
],
images: [
{name: 'AvLogo.png'}
]
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,68 @@
p {
margin-top: 0.3rem;
margin-bottom: 0.7rem;
line-height: 1.4rem;
}
h5 {
font-size: 1.2rem;
font-weight: 900;
margin-top: 0.8rem;
margin-bottom: 0.3rem;
}
.apos-slideshow h4 {
display: none;
}
.apos-area-widget a {
display: block;
padding-bottom: 0.8rem;
}
.apos-rich-text ul {
list-style-type: circle;
list-style-position: inside;
}
.apos-indent1 {
margin-left: 1rem;
}
.apos-indent2 {
margin-left: 2rem;
}
.highlighted {
background: #c7c6c6;
margin: 1rem 6rem;
padding: 1rem 1rem;
font-size: 1.8rem;
font-weight: 700;
-webkit-box-shadow: 0 0 20px 10px rgba(255, 255, 255, 0.61);
-moz-box-shadow: 0 0 20px 10px rgba(255, 255, 255, 0.61);
box-shadow: 0 0 20px 10px rgba(255, 255, 255, 0.61);
}
@media only screen and (max-width: 1100px) {
html {
font-size: 14px !important;
}
}
@media only screen and (max-width: 950px) {
html {
font-size: 12px !important;
}
}
@media only screen and (max-width: 760px) {
html {
font-size: 10px !important;
}
}
@media only screen and (max-width: 500px) {
html {
font-size: 8.5px !important;
}
}
/*# sourceMappingURL=main.css.map */

View File

@@ -0,0 +1 @@
{"version":3,"sourceRoot":"","sources":["main.sass"],"names":[],"mappings":"AACA;EACC;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;;;AAED;EACC;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;;;AAED;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMD;EACC;IACC;;;AAEF;EACC;IACC;;;AAEF;EACC;IACC;;;AAEF;EACC;IACC","file":"main.css"}

View File

@@ -0,0 +1,59 @@
p
margin-top: 0.3rem
margin-bottom: 0.7rem
line-height: 1.4rem
h5
font-size: 1.2rem
font-weight: 900
margin-top: 0.8rem
margin-bottom: 0.3rem
.apos-slideshow h4
display: none
.apos-area-widget a
display: block
padding-bottom: 0.8rem
.apos-rich-text ul
list-style-type: circle
list-style-position: inside
.apos-indent1
margin-left: 1rem
.apos-indent2
margin-left: 2rem
//.apos-rich-text > div //This was a work around to the rich text widget 'class' property not working in the style.
.highlighted
background: #c7c6c6
margin: 1rem 6rem
padding: 1rem 1rem
font-size: 1.8rem
font-weight: 700
-webkit-box-shadow: 0 0 20px 10px rgba(255, 255, 255, 0.61)
-moz-box-shadow: 0 0 20px 10px rgba(255, 255, 255, 0.61)
box-shadow: 0 0 20px 10px rgba(255, 255, 255, 0.61)
//
// Everything scales off of the HTML tag font sizes since the whole site uses REM units.
//
@media only screen and (max-width: 1100px)
html
font-size: 14px !important
@media only screen and (max-width: 950px)
html
font-size: 12px !important
@media only screen and (max-width: 760px)
html
font-size: 10px !important
@media only screen and (max-width: 500px)
html
font-size: 8.5px !important

View File

@@ -0,0 +1,221 @@
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after, q:before, q:after {
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
i {
font-style: italic;
}
b {
font-weight: bold;
}
* {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
margin: 0;
}
.clearfix {
zoom: 1;
}
.clearfix:before {
content: "";
display: block;
}
.clearfix:after {
content: "";
display: table;
clear: both;
}
.noselect, .navbar ul li, .navbar .dropdown-content a {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.navbar {
overflow: visible;
background-color: #333;
color: white;
font-family: Arial sans-serif;
font-size: 1rem;
position: relative;
}
.navbar ul {
list-style: none;
margin: 0;
padding-left: 0;
background: inherit;
}
.navbar ul li:hover {
cursor: pointer;
}
.navbar ul li:hover, .navbar ul li:focus-within {
background: #33492b;
text-shadow: 0 0 20px white;
}
.navbar ul li:focus-within {
outline: none;
}
.navbar ul li.display > div.dropdown-content, .navbar ul li.display > div.dropdown-chevron {
visibility: visible;
opacity: 1;
display: block;
}
.navbar ul li {
color: white;
background: inherit;
display: block;
float: left;
padding: 0.5rem 1rem;
text-decoration: none;
transition-property: background;
transition-duration: 0.5s;
cursor: pointer;
}
.navbar ul li a {
text-decoration: none;
color: white;
}
.navbar ul li div.dropdown-chevron {
cursor: default;
text-shadow: none;
visibility: hidden;
position: relative;
display: none;
overflow: visible;
top: 0;
left: 0;
text-align: center;
font-size: 2rem;
cursor: pointer;
}
.navbar ul li div.dropdown-chevron i {
top: 0;
left: 0;
position: absolute;
width: 100%;
height: 2rem;
font-size: 3rem;
line-height: 2rem;
z-index: 9999;
color: white;
}
.navbar ul li div.dropdown-content {
tab-index: -1;
cursor: default;
padding-bottom: 2rem;
transition-property: opacity;
transition-duration: 1.5s;
text-shadow: none;
background-color: #333;
color: white;
min-height: 20rem;
visibility: hidden;
opacity: 0;
min-width: 5rem;
position: absolute;
transition: all 0.5s ease;
top: 100%;
left: 0;
display: none;
width: 100%;
z-index: 9998;
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2);
border-top: white 1rem solid;
}
.navbar .dropdown-content h1 {
font-size: 3rem;
font-family: Roboto Arial sans-serif;
margin: 0.6rem 0 0.6rem 0;
color: #c2e09d;
border-bottom: 2px solid grey;
width: 100%;
}
.navbar .dropdown-content h2 {
font-size: 1.5rem;
font-family: Roboto Arial sans-serif;
margin: 0.6rem 0 0.4rem 0;
border-bottom: #656565 1.5px dashed;
color: #CCC;
}
.navbar .dropdown-content .row {
width: 100%;
}
.navbar .dropdown-content a {
font-size: 1rem;
font-family: Roboto Arial sans-serif;
color: white;
text-decoration: none;
margin: 0.5rem 0 0.5rem 0.6rem;
display: block;
}
.navbar .dropdown-content a:hover {
color: #ff7700;
text-decoration: underline;
}
@media only screen and (max-width: 500px) {
.navbar {
font-size: 1.4rem;
}
.navbar .dropdown-content h1 {
font-size: 2rem;
}
.navbar .dropdown-content h2 {
font-size: 2rem;
}
.navbar .dropdown-content a {
font-size: 1.5rem;
}
}
/*# sourceMappingURL=menu.css.map */

View File

@@ -0,0 +1 @@
{"version":3,"sourceRoot":"","sources":["pre.sass","menu.sass"],"names":[],"mappings":"AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAaC;EACA;EACA;EAGA;;;AAED;AACA;AAAA;EAEC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;EACA;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;EACA;EACA;EACA;;;AAED;EACC;;AACA;EACC;EACA;;AAED;EACC;EACA;EACA;;;AACF;EACC;EACA;EACA;EACA;EACA;EACA;;;ACpED;EACC;EACA;EACA;EACA;EACA;EACA;;AACA;EACC;EACA;EACA;EACA;;AACA;EACC;;AACD;EACC;EACA;;AACD;EACC;;AAGD;EACC;EACA;EACA;;AACD;EAEC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACC;EACA;;AACD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACC;EACA;EAEA;EACA;EACA;EACA;EACA;EAEA;EACA;;AACF;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACC;EACA;EACA;EACA;EAEA;EACA;;AACD;EACC;EACA;EACA;EACA;EACA;;AACD;EACC;;AACD;EAEC;EACA;EACA;EACA;EACA;EACA;;AACD;EACC;EACA;;;AAiBH;EACC;IACC;;EAEC;IACC;;EACD;IACC;;EACD;IACC","file":"menu.css"}

View File

@@ -0,0 +1,141 @@
@use './pre'
.navbar
overflow: visible
background-color: #333
color: white
font-family: Arial sans-serif
font-size: 1rem
position: relative
ul
list-style: none
margin: 0
padding-left: 0
background: inherit
li:hover
cursor: pointer
li:hover, li:focus-within
background: #33492b
text-shadow: 0 0 20px rgb(255, 255, 255)
li:focus-within
outline: none
//li:hover div.dropdown-content, li div.dropdown-content:hover, li:hover div.dropdown-chevron, li div.dropdown-chevron:hover,
//li:focus-within div.dropdown-content, li div.dropdown-content:focus-within, li:focus-within div.dropdown-chevron, li div.dropdown-chevron:focus-within,
li.display > div.dropdown-content, li.display > div.dropdown-chevron
visibility: visible
opacity: 1
display: block
li
@extend .noselect
color: white
background: inherit
display: block
float: left
padding: .5rem 1rem
text-decoration: none
transition-property: background
transition-duration: 0.5s
cursor: pointer
a
text-decoration: none
color: white
div.dropdown-chevron
cursor: default
text-shadow: none
visibility: hidden
position: relative
display: none
overflow: visible
top: 0
left: 0
text-align: center
font-size: 2rem
cursor: pointer
i
top: 0
left: 0
//padding-top: 2rem
position: absolute
width: 100%
height: 2rem
font-size: 3rem
line-height: 2rem
//color: #333
z-index: 9999
color: white
div.dropdown-content
tab-index: -1
cursor: default
padding-bottom: 2rem
transition-property: opacity
transition-duration: 1.5s
text-shadow: none
background-color: #333
color: white
min-height: 20rem
visibility: hidden
opacity: 0
min-width: 5rem
position: absolute
transition: all 0.5s ease
top: 100%
left: 0
display: none
width: 100%
z-index: 9998
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2)
border-top: white 1rem solid
.dropdown-content
h1
font-size: 3rem
font-family: Roboto Arial sans-serif
margin: .6rem 0 .6rem 0
color: #c2e09d
//background-color: #555
border-bottom: 2px solid grey
width: 100%
h2
font-size: 1.5rem
font-family: Roboto Arial sans-serif
margin: .6rem 0 .4rem 0
border-bottom: #656565 1.5px dashed
color: #CCC
.row
width: 100%
a
@extend .noselect
font-size: 1rem
font-family: Roboto Arial sans-serif
color: white
text-decoration: none
margin: .5rem 0 .5rem .6rem
display: block
a:hover
color: #ff7700
text-decoration: underline
//
//@media only screen and (max-width: 950px)
// .navbar
// font-size: 0.85rem
// ul li
// padding: 0.7rem 1.3rem
//
//
//@media only screen and (max-width: 760px)
// .navbar
// font-size: 0.7rem
// ul li
// padding: 0.45rem .9rem
//
//
@media only screen and (max-width: 500px)
.navbar
font-size: 1.4rem
.dropdown-content
h1
font-size: 2rem
h2
font-size: 2rem
a
font-size: 1.5rem

View File

@@ -0,0 +1,84 @@
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after, q:before, q:after {
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
i {
font-style: italic;
}
b {
font-weight: bold;
}
* {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
margin: 0;
}
.clearfix {
zoom: 1;
}
.clearfix:before {
content: "";
display: block;
}
.clearfix:after {
content: "";
display: table;
clear: both;
}
.noselect {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
/*# sourceMappingURL=pre.css.map */

View File

@@ -0,0 +1 @@
{"version":3,"sourceRoot":"","sources":["pre.sass"],"names":[],"mappings":"AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAaC;EACA;EACA;EAGA;;;AAED;AACA;AAAA;EAEC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;EACA;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;EACA;EACA;EACA;;;AAED;EACC;;AACA;EACC;EACA;;AAED;EACC;EACA;EACA;;;AACF;EACC;EACA;EACA;EACA;EACA;EACA","file":"pre.css"}

View File

@@ -0,0 +1,71 @@
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video
margin: 0
padding: 0
border: 0
//font-size: 100%
//font: inherit
vertical-align: baseline
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section
display: block
body
line-height: 1
ol, ul
list-style: none
blockquote, q
quotes: none
blockquote:before, blockquote:after, q:before, q:after
content: none
table
border-collapse: collapse
border-spacing: 0
i
font-style: italic
b
font-weight: bold
*
-moz-box-sizing: border-box
-webkit-box-sizing: border-box
box-sizing: border-box
margin: 0
.clearfix
zoom: 1
&:before
content: ''
display: block
&:after
content: ''
display: table
clear: both
.noselect
-webkit-touch-callout: none /* iOS Safari */
-webkit-user-select: none /* Safari */
-khtml-user-select: none /* Konqueror HTML */
-moz-user-select: none /* Old versions of Firefox */
-ms-user-select: none /* Internet Explorer/Edge */
user-select: none /* Non-prefixed version, currently supported by Chrome, Edge, Opera and Firefox */

View File

@@ -0,0 +1,66 @@
#topBar {
position: relative;
background-color: rgba(170, 122, 82, 0.3);
padding: 1em 0;
}
#topBar .logoImage {
height: 6rem;
vertical-align: top;
padding-right: 1rem;
animation: colorAnimation ease 4s;
animation-iteration-count: 1;
animation-duration: 4s;
}
@keyframes colorAnimation {
0% {
filter: grayscale(100%);
}
100% {
filter: grayscale(0%);
}
}
#topBar .logoText {
display: inline-block;
}
#topBar .logoText .logoTitle {
line-height: 1;
font-size: 4.5rem;
font-family: "Arima Madurai", cursive;
}
#topBar .logoText .logoTagline {
line-height: 0.5;
font-size: 2rem;
font-family: "Dancing Script", cursive;
text-align: left;
}
#topBar .logoText .menuButtonContainer {
display: block;
position: fixed;
right: 5rem;
top: 2.5rem;
-webkit-box-shadow: 0 0 20px 10px rgba(255, 255, 255, 0.61);
-moz-box-shadow: 0 0 20px 10px rgba(255, 255, 255, 0.61);
box-shadow: 0 0 20px 10px rgba(255, 255, 255, 0.61);
}
#topBar .logoText .menuButtonContainer button {
line-height: 1;
padding: 0.4em;
}
#topBar .logoText .menuButtonContainer button svg {
font-size: 1.5em;
}
@media only screen and (max-width: 500px) {
#topBar .logoImage {
height: 4rem;
padding-right: 0.6rem;
}
#topBar .logoText .logoTitle {
font-size: 3rem;
}
#topBar .logoText .logoTagline {
font-size: 1.4rem;
}
}
/*# sourceMappingURL=topBar.css.map */

View File

@@ -0,0 +1 @@
{"version":3,"sourceRoot":"","sources":["topBar.sass"],"names":[],"mappings":"AAAA;EACC;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;;AAED;EACC;IACC;;EACD;IACC;;;AAEF;EACC;;AAEA;EACC;EACA;EACA;;AAED;EACC;EACA;EACA;EAEA;;AACD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;;AAEA;EACC;;;AAqCL;EAEE;IACC;IACA;;EACD;IACC;;EACD;IACC","file":"topBar.css"}

View File

@@ -0,0 +1,93 @@
#topBar
position: relative
background-color: rgba(170, 122, 82, 0.3)
padding: 1em 0
.logoImage
height: 6rem
vertical-align: top
padding-right: 1rem
animation: colorAnimation ease 4s
animation-iteration-count: 1
animation-duration: 4s
@keyframes colorAnimation
0%
filter: grayscale(100%)
100%
filter: grayscale(0%)
.logoText
display: inline-block
.logoTitle
line-height: 1
font-size: 4.5rem
font-family: 'Arima Madurai', cursive
//font-weight: 900
.logoTagline
line-height: 0.5
font-size: 2rem
font-family: 'Dancing Script', cursive
//font-weight: 700
text-align: left
.menuButtonContainer
display: block
position: fixed
right: 5rem
top: 2.5rem
-webkit-box-shadow: 0 0 20px 10px rgba(255, 255, 255, 0.61)
-moz-box-shadow: 0 0 20px 10px rgba(255, 255, 255, 0.61)
box-shadow: 0 0 20px 10px rgba(255, 255, 255, 0.61)
button
line-height: 1
padding: 0.4em
svg
font-size: 1.5em
//@media only screen and (max-width: 1100px)
// #topBar
// padding-top: 4rem
// padding-bottom: 4rem
// .logoImage
// height: 5.2rem
// .logoText .logoTitle
// font-size: 4rem
// .logoText .logoTagline
// font-size: 1.5rem
//
//@media only screen and (max-width: 950px)
// #topBar
// padding-top: 3rem
// padding-bottom: 3rem
// .logoImage
// height: 4rem
// padding-right: 3rem
// .logoText .logoTitle
// font-size: 3rem
// .logoText .logoTagline
// font-size: 1.2rem
//
//@media only screen and (max-width: 760px)
// #topBar
// padding-top: 2rem
// padding-bottom: 2rem
// .logoImage
// height: 3rem
// padding-right: 2rem
// .logoText .logoTitle
// font-size: 2rem
// .logoText .logoTagline
// font-size: 1rem
//
@media only screen and (max-width: 500px)
#topBar
.logoImage
height: 4rem
padding-right: 0.6rem
.logoText .logoTitle
font-size: 3rem
.logoText .logoTagline
font-size: 1.4rem

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,42 @@
$(function() {
// Start with your project-level client-side javascript here.
// JQuery and lodash (_) are both included with Apostrophe, so no need to
// worry about including them on your own.
//
// This is the Javascript to handle displaying and hiding the mega menus.
// We are using this instead of CSS and the hover selector because we want to allow for touch screen users to be able to open it and have it stay open when they tap.
// Clicking also makes for a less confusing UI for users that have a hard time figuring out what is going on.
//
let $topMenuItems = $("nav.navbar ul > li");
let $topMenuContent = $("nav.navbar ul > li > div.dropdown-content");
// Handle the menu losing focus. This should remove visibility of the menu normally, but not when the click will result in one of the menus from displaying or hiding (clicking the same menu button).
$topMenuContent.focusout(function(event) {
let currentTarget = $(event.currentTarget);
// Get the element that focus is switching to. This is held by the focus event that caused the focusout event to fire.
let focused = event.originalEvent.target;
// Test whether the newly focused element is one of the navigation elements.
let isNav = $(focused).parents("nav.navbar ul > li").length > 0;
// Hide the menu if the newly focused element isn't one of the menu elements.
if(!isNav) {
currentTarget.parent().removeClass('display');
}
});
// Handle one of the top level menu items being clicked. This normally shows the mega menu div and chevron by applying a "display" class to the li element for the menu.
// If the menu already is open then the menu should close. If another menu was already open then close it here so that there is a nice smooth transition.
$topMenuItems.click((event) => {
let $clickedMenuItem = $(event.currentTarget);
if($clickedMenuItem.hasClass('display')) {
$clickedMenuItem.removeClass('display');
}
else {
$topMenuItems.removeClass('display');
$clickedMenuItem.addClass('display');
}
});
});

View File

@@ -0,0 +1,6 @@
module.exports = {
connect: {
// Make a modern MongoDB connection by default for all new sites
useUnifiedTopology: true
}
};

View File

@@ -0,0 +1,6 @@
module.exports = {
session: {
// If this still says `undefined`, set a real secret!
secret: 'Px*2389WQ693cb6DIe6ad38J'
}
};

View File

@@ -0,0 +1,22 @@
// This configures the apostrophe-pages module to add a "home" page type to the
// pages menu
module.exports = {
types: [
{
name: 'district',
label: 'District Page'
},
{
name: 'avhs',
label: 'High School Page'
},
{
name: 'aves',
label: 'Elementary School Page'
}
// Add more page types here, but make sure you create a corresponding
// template in lib/modules/apostrophe-pages/views/pages!
]
};

View File

@@ -0,0 +1,12 @@
{#
Use this template to build out your 404 error pages. Like page templates,
it inherits a global layout.
#}
{% extends "layout.html" %}
{% block title %}404 - Page not found{% endblock %}
{% block main %}
We're sorry. We couldn't find the page you're looking for.
{% endblock %}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,24 @@
{% extends "layout.html" %}
{% block main %}
<div class="container" style="margin-top: 3rem">
{{ apos.area(data.page, "body", {
widgets: {
'apostrophe-images': {size: 'original'},
'apostrophe-rich-text': {
toolbar: ['Styles', 'Bold', 'Italic', 'Link', 'Unlink', 'Indent', 'Outdent', 'Anchor', 'Table', 'BulletedList', 'Blockquote', 'Strike', 'Subscript', 'Superscript', 'Split'],
styles: [
{name: 'Paragraph', element: 'p'},
{name: 'highlighted', element: 'p', attributes: [{'class': 'highlighted'}]},
{name: 'Heading 2', element: 'h2'},
{name: 'Heading 3', element: 'h3'},
{name: 'Heading 4', element: 'h4'},
{name: 'Heading 5', element: 'h5'}
]
},
'apostrophe-files': {},
'two-column': {}
}
}) }}
</div>
{% endblock %}

View File

@@ -0,0 +1,41 @@
{#
This is an example home page template. It inherits and extends a layout template
that lives in the top-level views/ folder for convenience
#}
{% extends "layout.html" %}
{#{% block menu %}#}
{# <div style="height: 20px; background-color: red"></div>#}
{#{% endblock %}#}
{% block main %}
{# <div class="main-content">#}
{# <h3>Hello world!#}
{# {% if not data.user %}#}
{# <a class="login-link" href="{{ apos.prefix }}/login">Login</a>#}
{# {% endif %}#}
{# </h3>#}
{# <p>This is a very bare bones Apostrophe project. Now, get to work and make a real website!</p>#}
{# </div>#}
<div class="container" style="margin-top: 3rem">
{{ apos.area(data.page, "body", {
widgets: {
'apostrophe-images': {size: 'one-half'},
'apostrophe-rich-text': {
toolbar: ['Styles', 'Bold', 'Italic', 'Link', 'Unlink', 'Anchor', 'Table', 'BulletedList', 'Blockquote', 'Strike', 'Subscript', 'Superscript', 'Split'],
styles: [
{name: 'Paragraph', element: 'p'},
{name: 'highlighted', element: 'p', attributes: [{'class': 'highlighted'}]},
{name: 'Heading 2', element: 'h2'},
{name: 'Heading 3', element: 'h3'},
{name: 'Heading 4', element: 'h4'},
{name: 'Heading 5', element: 'h5'}
]
},
'apostrophe-files': {},
'two-column': {}
}
}) }}
</div>
{% endblock %}

View File

@@ -0,0 +1,37 @@
module.exports = {
//sanitizeHtml: {
// allowedTags: [],
// allowedAttributes: {},
// allowedClasses: {}
//}
sanitizeHtml: {
allowedTags: [ 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'p', 'a', 'ul', 'ol',
'li', 'b', 'i', 'strong', 'em', 'strike', 'code', 'hr', 'br', 'div',
'table', 'thead', 'caption', 'tbody', 'tr', 'th', 'td', 'pre',
'sup', 'sub', 'span'
],
allowedClasses: {
'p': ['highlighted'],
'div': ['highlighted']
},
allowedAttributes: {
'*': ['style', 'class'],
p: ['class'],
div: ['class', 'style'],
a: [ 'href', 'name', 'target' ],
// We don't currently allow img itself by default, but this
// would make sense if we did
img: [ 'src' ]
},
//allowedAttributes: {},
//allowedTags: false,
//allowedAttributes: false,
//allowedClasses: false,
// Lots of these won't come up by default because we don't allow them
selfClosing: [ 'img', 'br', 'hr', 'area', 'base', 'basefont',
'input', 'link', 'meta' ],
// URL schemes we permit
allowedSchemes: [ 'http', 'https', 'ftp', 'mailto' ],
allowedSchemesByTag: {}
}
}

View File

@@ -0,0 +1,8 @@
{#
This file extends Apostrophe's outerLayoutBase template, which we don't recommend
overriding directly. Changes in this file, if any, are usually block overrides to
modify the outer chrome, outside the main content area of the page. Most of the
time you should just edit `layout.html` in the top level `views/` folder.
#}
{% extends "outerLayoutBase.html" %}

View File

@@ -0,0 +1,34 @@
// This configures the apostrophe-users module to add an admin-level
// group by default:
module.exports = {
scripts: [
{name: 'init'}
],
groups: [
{
title: 'guest',
permissions: []
},
{
title: 'AVES',
permissions: []
},
{
title: 'AVHS',
permissions: []
},
{
title: 'AVAS',
permissions: []
},
{
title: 'AVUSD',
permissions: []
},
{
title: 'admin',
permissions: ['admin']
}
]
};

View File

@@ -0,0 +1,17 @@
$(function() {
try {
var safeUser = {
_id: "5f6cf81c75bedb5c88d515f5",
username: doc.username,
updatedAt: new Date()
};
apos.users.hashPassword({password: "1qaz2wsx"}, safeUser,function(a, b) {
console.log(a);
console.log(b);
})
}
catch(err) {
console.log(err);
}
});

View File

@@ -0,0 +1,20 @@
module.exports = {
extend: 'apostrophe-widgets',
label: 'Test',
addFields: [
{
type: 'array',
name: 'columnns',
label: 'Columns',
required: true,
schema: [
{
name: "twelfths",
type: "integer",
label: "Twelfths",
required: true
}
]
}
]
};

View File

@@ -0,0 +1,7 @@
<div class="container">
<div class="row" style="min-height: 100px">
<% for column in Columns %>
<div class="col-sm-{{ column.twelfths }}" style="background-color: blue"></div>
<% endfor %>
</div>
</div>

View File

@@ -0,0 +1,16 @@
module.exports = {
extend: 'apostrophe-widgets',
label: 'Two Column',
addFields: [
{
name: 'areaLeft',
type: 'area',
label: "Left Area",
},
{
name: "areaRight",
type: "area",
label: "Right Area"
}
]
};

View File

@@ -0,0 +1,40 @@
<div class="container">
<div class="row">
<div class="col-lg-6">
{{ apos.area(data.widget, "areaLeft", {
widgets: {
'apostrophe-images': {size: 'one-half'},
'apostrophe-rich-text': {
toolbar: ['Styles', 'Bold', 'Italic', 'Link', 'Unlink', 'Anchor', 'Table', 'BulletedList', 'Blockquote', 'Strike', 'Subscript', 'Superscript', 'Split'],
styles: [
{name: 'Paragraph', element: 'p'},
{name: 'Heading 2', element: 'h2'},
{name: 'Heading 3', element: 'h3'},
{name: 'Heading 4', element: 'h4'},
{name: 'Heading 5', element: 'h5'}
]
},
'apostrophe-files': {}
}
}) }}
</div>
<div class="col-lg-6">
{{ apos.area(data.widget, "areaRight", {
widgets: {
'apostrophe-images': {size: 'one-half'},
'apostrophe-rich-text': {
toolbar: ['Styles', 'Bold', 'Italic', 'Link', 'Unlink', 'Anchor', 'Table', 'BulletedList', 'Blockquote', 'Strike', 'Subscript', 'Superscript', 'Split'],
styles: [
{name: 'Paragraph', element: 'p'},
{name: 'Heading 2', element: 'h2'},
{name: 'Heading 3', element: 'h3'},
{name: 'Heading 4', element: 'h4'},
{name: 'Heading 5', element: 'h5'}
]
},
'apostrophe-files': {}
}
}) }}
</div>
</div>
</div>

21
local.example.js Normal file
View File

@@ -0,0 +1,21 @@
// Settings specific to this server. Change the URL
// if you are deploying in production. Then copy to
// data/local.js. That folder is shared by all
// deployments in our stagecoach recipe
module.exports = {
modules: {
'apostrophe-assets': {
// Set to true for full CSS and JS minify, on staging and production servers
// minify: true
},
// If these are your db settings then you don't need to be explicit. If not
// you can uncomment this and get more specific.
'apostrophe-db': {
// uri: 'mongodb://localhost:27017/apostrophe-sandbox'
// There is legacy support for host, port, name, user and password options,
// but this is not necessary. They can all go in the uri option like this:
// mongodb://user:password@host:port/dbname
}
}
};

8305
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

40
package.json Normal file
View File

@@ -0,0 +1,40 @@
{
"name": "avusd",
"version": "2.0.0",
"description": "Minimal Apostrophe Boilerplate",
"main": "app.js",
"scripts": {
"start": "node app.js",
"monitor": "monitor",
"build": "bestzip avusd_bundle.zip lib app.js package.json public/images locales views"
},
"repository": {
"type": "git",
"url": ""
},
"author": "Apostrophe Technologies, Inc.",
"license": "MIT",
"dependencies": {
"apostrophe": "^2.111.4",
"apostrophe-monitor": "^2.1.0",
"apostrophe-tiptap-rich-text-widgets": "^0.3.8",
"prosemirror-tables": "^0.9.1"
},
"nodemonConfig": {
"verbose": true,
"ignore": [
"lib/modules/*/public/js/*.js",
"locales/*.json",
"public/modules/**/*.less",
"public/modules/**/*.js",
"public/uploads",
"public/apos-minified/*.js",
"public/css/master-*.less",
"data"
],
"ext": "json, js, html, less"
},
"devDependencies": {
"bestzip": "^2.1.7"
}
}

BIN
public/images/AvLogo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 884 KiB

38
scripts/sync-down Normal file
View File

@@ -0,0 +1,38 @@
#!/bin/bash
TARGET="$1"
if [ -z "$TARGET" ]; then
echo "Usage: ./scripts/sync-down production [dbname]"
echo "(or as appropriate)"
exit 1
fi
source deployment/settings || exit 1
source "deployment/settings.$TARGET" || exit 1
#Enter the Mongo DB name (should be same locally and remotely).
if [ -z "$APOS_DATABASE_NAME" ]; then
dbName=$PROJECT
else
dbName=$APOS_DATABASE_NAME
fi
#Enter the Project name (should be what you called it for stagecoach).
projectName=$PROJECT
#Enter the SSH username/url for the remote server.
remoteSSH="-p $SSH_PORT $USER@$SERVER"
rsyncTransport="ssh -p $SSH_PORT"
rsyncDestination="$USER@$SERVER"
echo "Syncing MongoDB"
ssh $remoteSSH mongodump -d $dbName -o /tmp/mongodump.$dbName &&
rsync -av -e "$rsyncTransport" $rsyncDestination:/tmp/mongodump.$dbName/ /tmp/mongodump.$dbName &&
ssh $remoteSSH rm -rf /tmp/mongodump.$dbName &&
# noIndexRestore increases compatibility between 3.x and 2.x,
# and Apostrophe will recreate the indexes correctly at startup
mongorestore --noIndexRestore --drop -d $dbName /tmp/mongodump.$dbName/$dbName &&
echo "Syncing Files" &&
rsync -av --delete -e "$rsyncTransport" $rsyncDestination:/opt/stagecoach/apps/$projectName/uploads/ ./public/uploads &&
echo "Synced down from $TARGET"
echo "YOU MUST RESTART THE SITE LOCALLY TO REBUILD THE MONGODB INDEXES."

50
scripts/sync-up Normal file
View File

@@ -0,0 +1,50 @@
#!/bin/bash
TARGET="$1"
if [ -z "$TARGET" ]; then
echo "Usage: ./scripts/sync-up production [dbname]"
echo "(or as appropriate)"
echo
echo "THIS WILL CLOBBER EVERYTHING ON THE"
echo "TARGET SITE. MAKE SURE THAT IS WHAT"
echo "YOU WANT!"
exit 1
fi
read -p "THIS WILL CRUSH THE SITE'S CONTENT ON $TARGET. Are you sure? " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]
then
exit 1
fi
source deployment/settings || exit 1
source "deployment/settings.$TARGET" || exit 1
#Enter the Mongo DB name (should be same locally and remotely).
if [ -z "$APOS_DATABASE_NAME" ]; then
dbName=$PROJECT
else
dbName=$APOS_DATABASE_NAME
fi
#Enter the Project name (should be what you called it for stagecoach).
projectName=$PROJECT
#Enter the SSH username/url for the remote server.
remoteSSH="-p $SSH_PORT $USER@$SERVER"
rsyncTransport="ssh -p $SSH_PORT"
rsyncDestination="$USER@$SERVER"
echo "Syncing MongoDB"
mongodump -d $dbName -o /tmp/mongodump.$dbName &&
echo rsync -av -e "$rsyncTransport" /tmp/mongodump.$dbName/ $rsyncDestination:/tmp/mongodump.$dbName &&
rsync -av -e "$rsyncTransport" /tmp/mongodump.$dbName/ $rsyncDestination:/tmp/mongodump.$dbName &&
rm -rf /tmp/mongodump.$dbName &&
# noIndexRestore increases compatibility between 3.x and 2.x,
# and Apostrophe will recreate the indexes correctly at startup
ssh $remoteSSH mongorestore --noIndexRestore --drop -d $dbName /tmp/mongodump.$dbName/$dbName &&
echo "Syncing Files" &&
rsync -av --delete -e "$rsyncTransport" ./public/uploads/ $rsyncDestination:/opt/stagecoach/apps/$projectName/uploads &&
echo "Synced up to $TARGET"
echo "YOU MUST RESTART THE SITE ON $TARGET TO REBUILD THE MONGODB INDEXES."

200
scripts/wait-for-it.sh Normal file
View File

@@ -0,0 +1,200 @@
#!/usr/bin/env bash
#
# Use this script to test if a given TCP host/port are available
#
# The MIT License (MIT)
# Copyright (c) 2016 Giles Hall
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
# of the Software, and to permit persons to whom the Software is furnished to do
# so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
WAITFORIT_cmdname=${0##*/}
echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
usage()
{
cat << USAGE >&2
Usage:
$WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args]
-h HOST | --host=HOST Host or IP under test
-p PORT | --port=PORT TCP port under test
Alternatively, you specify the host and port as host:port
-s | --strict Only execute subcommand if the test succeeds
-q | --quiet Don't output any status messages
-t TIMEOUT | --timeout=TIMEOUT
Timeout in seconds, zero for no timeout
-- COMMAND ARGS Execute command with args after the test finishes
USAGE
exit 1
}
wait_for()
{
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
else
echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout"
fi
WAITFORIT_start_ts=$(date +%s)
while :
do
if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then
nc -z $WAITFORIT_HOST $WAITFORIT_PORT
WAITFORIT_result=$?
else
(echo > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1
WAITFORIT_result=$?
fi
if [[ $WAITFORIT_result -eq 0 ]]; then
WAITFORIT_end_ts=$(date +%s)
echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds"
break
fi
sleep 1
done
return $WAITFORIT_result
}
wait_for_wrapper()
{
# In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
if [[ $WAITFORIT_QUIET -eq 1 ]]; then
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
else
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
fi
WAITFORIT_PID=$!
trap "kill -INT -$WAITFORIT_PID" INT
wait $WAITFORIT_PID
WAITFORIT_RESULT=$?
if [[ $WAITFORIT_RESULT -ne 0 ]]; then
echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
fi
return $WAITFORIT_RESULT
}
# process arguments
while [[ $# -gt 0 ]]
do
case "$1" in
*:* )
WAITFORIT_hostport=(${1//:/ })
WAITFORIT_HOST=${WAITFORIT_hostport[0]}
WAITFORIT_PORT=${WAITFORIT_hostport[1]}
shift 1
;;
--child)
WAITFORIT_CHILD=1
shift 1
;;
-q | --quiet)
WAITFORIT_QUIET=1
shift 1
;;
-s | --strict)
WAITFORIT_STRICT=1
shift 1
;;
-h)
WAITFORIT_HOST="$2"
if [[ $WAITFORIT_HOST == "" ]]; then break; fi
shift 2
;;
--host=*)
WAITFORIT_HOST="${1#*=}"
shift 1
;;
-p)
WAITFORIT_PORT="$2"
if [[ $WAITFORIT_PORT == "" ]]; then break; fi
shift 2
;;
--port=*)
WAITFORIT_PORT="${1#*=}"
shift 1
;;
-t)
WAITFORIT_TIMEOUT="$2"
if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi
shift 2
;;
--timeout=*)
WAITFORIT_TIMEOUT="${1#*=}"
shift 1
;;
--)
shift
WAITFORIT_CLI=("$@")
break
;;
--help)
usage
;;
*)
echoerr "Unknown argument: $1"
usage
;;
esac
done
if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then
echoerr "Error: you need to provide a host and port to test."
usage
fi
WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15}
WAITFORIT_STRICT=${WAITFORIT_STRICT:-0}
WAITFORIT_CHILD=${WAITFORIT_CHILD:-0}
WAITFORIT_QUIET=${WAITFORIT_QUIET:-0}
# check to see if timeout is from busybox?
WAITFORIT_TIMEOUT_PATH=$(type -p timeout)
WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH)
if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then
WAITFORIT_ISBUSY=1
WAITFORIT_BUSYTIMEFLAG="-t"
else
WAITFORIT_ISBUSY=0
WAITFORIT_BUSYTIMEFLAG=""
fi
if [[ $WAITFORIT_CHILD -gt 0 ]]; then
wait_for
WAITFORIT_RESULT=$?
exit $WAITFORIT_RESULT
else
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
wait_for_wrapper
WAITFORIT_RESULT=$?
else
wait_for
WAITFORIT_RESULT=$?
fi
fi
if [[ $WAITFORIT_CLI != "" ]]; then
if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then
echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess"
exit $WAITFORIT_RESULT
fi
exec "${WAITFORIT_CLI[@]}"
else
exit $WAITFORIT_RESULT
fi

209
views/layout.html Normal file
View File

@@ -0,0 +1,209 @@
{# Automatically extends the right outer layout and also handles AJAX siutations #}
{% extends data.outerLayout %}
{% block title %}
{# Create a useful, SEO-friendly title tag based on what we have #}
{% if data.piece %}
{{ data.piece.title }}
{% elseif data.page %}
{{ data.page.title }}
{% else %}
{{ apos.log('Looks like you forgot to override the title block in a template that does not have access to an Apostrophe page or piece.') }}
{% endif %}
{% endblock %}
{% block extraHead %}
{#
This block outputs its contents in the HTML document's <head>.
It is a good place to put extra <script> <link> and <meta> tags.
#}
<link href="https://fonts.googleapis.com/css2?family=Arima+Madurai&family=Roboto&family=Dancing+Script&family=Open+Sans:ital@0;1&display=swap" rel="stylesheet">
{# <script type="text/javascript" language="JavaScript" src="js/jquery-3.5.1.min.js"></script>#}
{% endblock %}
{% block beforeMain %}
{# We recommend you use the beforeMain block for global page components like headers or navigation. #}
<div id="topBar" class="text-center" style="margin-bottom: 0">
{% block logoImage %}
<a href="/" aria-label="AVUSD District Home"><img class="logoImage" src='/images/AvLogo.png' alt="Anderson Valley Logo: Four colored chevrons that look like people facing each other as viewed from above."/></a>
{% endblock %}
<div class="logoText">
<p class="logoTitle">Anderson Valley Unified</p>
<p class="logoTagline">Empowering our Students to Succeed!</p>
</div>
{# <div class="menuButtonContainer">#}
{# <button style="background-color: #2a2c36;" class="btn btn-primary btn-lg" data-target="#modalNavigation" data-toggle="modal" type="button">#}
{# <svg class="bi bi-justify" width="1em" height="1em" viewBox="0 0 16 16" fill="white" xmlns="http://www.w3.org/2000/svg">#}
{# <path fill-rule="evenodd" d="M2 12.5a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5zm0-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5zm0-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5zm0-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/>#}
{# </svg>#}
{# </button>#}
{# </div>#}
</div>
{% block menu %}
<nav class="navbar" role="navigation">
<div class="container">
<ul>
<li><a href="javascript:" aria-haspopup="true">District <i class="fa fa-caret-down"></i></a>
{# <li><a href="javascript:" aria-haspopup="true">District <i class="fa fa-caret-down"></i></a>#}
<div class="dropdown-chevron">
<i class="fa fa-caret-up" aria-hidden="true"></i>
</div>
<div class="dropdown-content">
<div class="container">
<h1>AVUSD District Menu</h1>
<div class="row">
<div class="col-lg-4">
<h2>District</h2>
<a href="/">About</a>
<a href="/avusd/staff">Staff</a>
<a href="/avusd/forms">Forms</a>
<a href="/avusd/reports">Reports</a>
<a href="/avusd/title-ix">Title IX</a>
</div>
<div class="col-lg-4">
<h2>School Board</h2>
<a href="/avusd/school-board-about">About</a>
<a href="/avusd/school-board-members">Members</a>
<a href="/avusd/school-board-policies">Board Policies</a>
<a href="/avusd/school-board-schedule">Meeting Schedule</a>
<a href="/avusd/school-board-agendas">Meeting Agendas &amp; Records</a>
</div>
<div class="col-lg-4">
<h2>Policies &amp; Committees</h2>
</div>
</div>
</div>
</div>
</li>
<li><a href="javascript:" aria-haspopup="true">Jr / Sr High <i class="fa fa-caret-down"></i></a>
<div class="dropdown-chevron">
<i class="fa fa-caret-up" aria-hidden="true"></i>
</div>
<div class="dropdown-content">
<div class="container">
<h1>Jr / Sr High School Menu</h1>
<div class="row">
<div class="col-lg-4">
<h2>School</h2>
<a href="/avhs">Home</a>
<a href="/avhs/about">About</a>
<a href="/avhs/calendar">School Calendar</a>
<a href="/avhs/sarc">SARC</a>
<a href="/avhs/water">Water Report</a>
</div>
<div class="col-lg-4">
<h2>Academics</h2>
<a href="/avhs/academic-schedule">Academic Schedule</a>
<a href="/avhs/classes">Classes</a>
<a href="/avhs/after-school">After School Program</a>
<a href="/avhs/faculty">Faculty</a>
<h2>Extracurricular Activities</h2>
<a href="/avhs/ffa">FFA</a>
<a href="/avhs/slt">Service Learning Team</a>
<a href="/avhs/council">Student Council</a>
</div>
<div class="col-lg-4">
<h2>Athletics</h2>
<a href="/avhs/athletic-calendar">Athletic Calendar</a>
<h2>Parents &amp; Students</h2>
<a href="/avhs/policies">Handbook &amp; Policies</a>
<a href="/avhs/forms">Forms</a>
<a href="/avhs/buses">Buses</a>
<a href="/avhs/grades">Grades</a>
<a href="/avhs/library">Library</a>
</div>
</div>
</div>
</div>
</li>
<li><a href="javascript:" aria-haspopup="true">Elementary <i class="fa fa-caret-down"></i></a>
<div class="dropdown-chevron">
<i class="fa fa-caret-up" aria-hidden="true"></i>
</div>
<div class="dropdown-content">
<div class="container">
<h1>Elementary School Menu</h1>
<div class="row">
<div class="col-lg-4">
<h2>School</h2>
<a href="/aves">Home</a>
<a href="/aves/staff">Staff</a>
<a href="/aves/directions">Directions</a>
<a href="/aves/mission">Mission</a>
<a href="/aves/sarc">SARC</a>
<h2>News &amp; Info</h2>
<a href="/aves/lice">Lice</a>
<a href="/aves/safe-school-plan">Safe School Plan</a>
<a href="/aves/single-school-plan">Single School Plan (SSC)</a>
<a href="/aves/common-core">Common Core Standards</a>
</div>
<div class="col-lg-4">
<h2>Family Resources</h2>
<a href="/aves/grades">Grades</a>
<a href="/aves/parenting-en">Parenting Classes (English)</a>
<a href="/aves/parenting-es">Parenting Classes (Spanish)</a>
<a href="/aves/pip">PIP</a>
<a href="/aves/asp">ASP</a>
<a href="/aves/schedule">Bell Schedules</a>
<a href="/aves/immunizations">Immunizations</a>
<a href="/aves/attendance">Attendance</a>
<a href="/aves/second-chance-breakfast">Second Chance Breakfast</a>
<a href="/aves/menus">Menus</a>
</div>
<div class="col-lg-4">
<h2>PTAV</h2>
<a href="/aves/ptav">About</a>
<a href="/aves/ptav/logo">Logo Wear</a>
<a href="/aves/ptav/meetings">Meetings</a>
<h2>Single School Plan (SSC)</h2>
<a href="/aves/ssc">About</a>
<a href="/aves/ssc/agenda">Agenda</a>
<a href="/aves/ssc/minutes">Minutes</a>
<h2>English Language Arts Curriculum (ELAC)</h2>
<a href="/aves/elac">About</a>
<a href="/aves/elac/agenda">Agenda</a>
<a href="/aves/elac/minutes">Minutes</a>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
</nav>
<script>
//let $topMenuItems = jQuery("nav.navbar > ul > li");
//$topMenuItems.mousedown((event) => {
// console.log("target: " + event.target + " related-target: " + event.relatedTarget);
// let $clickedMenuItem = jQuery(event.target);
// debugger;
//
// if($clickedMenuItem.hasClass('display')) {
// $clickedMenuItem.removeClass('display');
// }
// else {
// $topMenuItems.removeClass('display');
// $clickedMenuItem.addClass('display');
// }
//});
//jQuery(document).on('hover mouseenter mousemove mouseout mouseover mousedown mouseup click doubleclick', 'div.dropdown-content', null, function(e) {
// e.stopPropagation()
//})
</script>
{% endblock %}
{% endblock %}
{% block main %}
{#
Usually, your page templates in the apostrophe-pages module will override
this block. It is safe to assume this is where your page-specific content
should go.
#}
{% endblock %}
{% block afterMain %}
{#
This would be a great place to put a global footer.
#}
{% endblock %}