Compare commits

..

6 commits

7 changed files with 442 additions and 5 deletions

18
.github/workflows/deploy.yml vendored Normal file
View file

@ -0,0 +1,18 @@
name: Deploy to Cloudflare Workers
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '24'
- run: npm install
- uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}

1
.gitignore vendored
View file

@ -1,2 +1 @@
wrangler.toml
node_modules node_modules

6
.mise.toml Normal file
View file

@ -0,0 +1,6 @@
[tools]
node = "24.11.1"
[tasks]
deploy = "npx wrangler deploy"
dev = "npx wrangler dev"

119
README.md
View file

@ -10,6 +10,7 @@ The worker does a few things:
cookies can be established for login cookies can be established for login
* On a home page load, will insert the home page content and remove the * On a home page load, will insert the home page content and remove the
Javascript on the page that tries to get it after the fact Javascript on the page that tries to get it after the fact
* Serves static assets from the `/static` directory
If login gets "broken", its because the origin HTML has changed and the regexs If login gets "broken", its because the origin HTML has changed and the regexs
need adjustment. There are http headers that tell you if this is happening. need adjustment. There are http headers that tell you if this is happening.
@ -17,11 +18,125 @@ need adjustment. There are http headers that tell you if this is happening.
Broken here would mean that clicking login forces you through the multiple Broken here would mean that clicking login forces you through the multiple
drop downs to select site. drop downs to select site.
This section should be in your wrangler.toml file. Replace with the correct ## Configuration
values of course.
Update your `wrangler.toml` file with your Troopmaster site details:
```toml ```toml
name = "your-worker-name"
account_id = "your-cloudflare-account-id"
compatibility_date = "2025-11-25"
routes = [
{ pattern = "yoursite.org/*", zone_id = "your-zone-id" },
{ pattern = "*.yoursite.org/*", zone_id = "your-zone-id" }
]
[assets]
directory = "./static"
binding = "ASSETS"
[vars]
TMSITEID = "your-troopmaster-site-id"
TMSITENAME = "YourSiteName"
```
### Example Configuration (troop618.org)
```toml
name = "troop618"
account_id = "c7221b4e158b0c8f6009a627d5a6a41d"
compatibility_date = "2025-11-25"
routes = [
{ pattern = "troop618.org/*", zone_id = "62922e2b7c3bb7baee2d472943cfd594" },
{ pattern = "*.troop618.org/*", zone_id = "62922e2b7c3bb7baee2d472943cfd594" }
]
[assets]
directory = "./static"
binding = "ASSETS"
[vars] [vars]
TMSITEID = "203232" TMSITEID = "203232"
TMSITENAME = "Troop618" TMSITENAME = "Troop618"
``` ```
## Adding Static Routes
To serve static content from specific paths:
1. Place your files in the `/static` directory matching the URL structure
- Example: `/static/tree/index.html` serves at `/tree` or `/tree/`
2. Add the route check in `src/index.js` in the `handleRequest` function:
```javascript
if (url.pathname.startsWith('/your-path')) {
return env.ASSETS.fetch(request);
}
```
3. Add additional path checks as needed for each static route
## Development
### Prerequisites
- Node.js (v24 or later recommended)
- Cloudflare account with Workers enabled
### Install Dependencies
```bash
npm install
```
### Local Development
```bash
npx wrangler dev
```
This starts a local server that mimics the Cloudflare Workers environment.
## Deployment
### Manual Deployment
```bash
npx wrangler deploy
```
### Automated Deployment (GitHub)
1. Go to your Cloudflare dashboard → Workers & Pages
2. Create a new Worker from your GitHub repository
3. Configure the following:
- Production branch: `main` (or your default branch)
- Build command: (leave empty)
- Build output directory: (leave empty)
4. Add environment variables in the Cloudflare dashboard if needed
5. Every push to your configured branch will automatically deploy
### CI/CD with GitHub Actions
Create `.github/workflows/deploy.yml`:
```yaml
name: Deploy to Cloudflare Workers
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '24'
- run: npm install
- uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
```
Add `CLOUDFLARE_API_TOKEN` to your repository secrets.

View file

@ -112,9 +112,14 @@ async function homePage(origin) {
* Respond with whatever origin gives us * Respond with whatever origin gives us
* @param {Request} request * @param {Request} request
*/ */
async function handleRequest(request) { async function handleRequest(request, env) {
let response; let response;
try { try {
// Check for static assets first
const url = new URL(request.url);
if (url.pathname.startsWith('/tree')) {
return env.ASSETS.fetch(request);
}
// curl -b TroopMasterWebSiteID=203232 -v https://tmweb.troopmaster.com/Website/Home // curl -b TroopMasterWebSiteID=203232 -v https://tmweb.troopmaster.com/Website/Home
const origin = 'https://tmweb.troopmaster.com/Website/Home'; const origin = 'https://tmweb.troopmaster.com/Website/Home';
const originHost = 'https://tmweb.troopmaster.com'; const originHost = 'https://tmweb.troopmaster.com';
@ -164,5 +169,5 @@ async function handleRequest(request) {
// neither browser nor node. This is the hook into the CF Worker ecosystem, // neither browser nor node. This is the hook into the CF Worker ecosystem,
// so we need to have this code and is safe to disable eslint for this line // so we need to have this code and is safe to disable eslint for this line
addEventListener('fetch', (event) => { // eslint-disable-line no-restricted-globals addEventListener('fetch', (event) => { // eslint-disable-line no-restricted-globals
event.respondWith(handleRequest(event.request)); event.respondWith(handleRequest(event.request, event.env));
}); });

277
static/tree/index.html Normal file
View file

@ -0,0 +1,277 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Troop 5/618 - Christmas Tree Recycling - Troop 5618 & 618</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
line-height: 1.6;
color: #333;
background-color: #fff;
padding: 20px;
}
h1 {
color: #333;
margin-bottom: 20px;
font-size: 2em;
text-align: center;
}
h2 {
color: #f68424;
margin: 30px 0 15px 0;
font-size: 1.5em;
border-bottom: 2px solid #f68424;
padding-bottom: 10px;
}
.dates {
background-color: #f68424;
color: #333;
padding: 25px;
border-radius: 5px;
margin: 20px 0;
text-align: center;
font-size: 1.2em;
font-weight: bold;
border: 3px solid #333;
}
.dates-header {
font-size: 0.9em;
margin-bottom: 10px;
text-transform: uppercase;
letter-spacing: 1px;
}
.weekend {
font-size: 1.1em;
margin: 5px 0;
}
.highlight-box {
background-color: #fff3e0;
border-left: 4px solid #f68424;
padding: 15px;
margin: 15px 0;
}
.button {
display: inline-block;
background-color: #f68424;
color: white;
padding: 15px 30px;
text-decoration: none;
border-radius: 5px;
font-weight: bold;
font-size: 1.1em;
margin: 10px 5px;
text-align: center;
}
.button:hover {
background-color: #d67320;
color: white !important;
}
.button-secondary {
background-color: #0070ba;
}
.button-secondary:hover {
background-color: #005a94;
}
ul {
margin-left: 20px;
margin-top: 10px;
}
li {
margin-bottom: 10px;
}
.donation-amount {
font-size: 1.2em;
font-weight: bold;
color: #f68424;
margin: 10px 0;
}
.steps {
counter-reset: step-counter;
list-style: none;
margin-left: 0;
}
.steps li {
counter-increment: step-counter;
margin-bottom: 15px;
padding-left: 40px;
position: relative;
}
.steps li::before {
content: counter(step-counter);
position: absolute;
left: 0;
top: 0;
background-color: #f68424;
color: white;
width: 28px;
height: 28px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
}
.faq-item {
margin-bottom: 20px;
}
.faq-question {
font-weight: bold;
color: #f68424;
margin-bottom: 5px;
}
.warning {
background-color: #fff3cd;
border-left: 4px solid #ffc107;
padding: 15px;
margin: 15px 0;
}
.center {
text-align: center;
}
.section {
margin-bottom: 30px;
}
a {
color: #f68424;
}
a:hover {
color: #d67320;
}
@media (max-width: 600px) {
body {
padding: 10px;
}
h1 {
font-size: 1.5em;
}
.button {
display: block;
margin: 10px 0;
}
}
</style>
</head>
<body>
<h1>🎄 Scouting America Troop 5618 & 618<br>Annual Christmas Tree Recycling Fundraiser</h1>
<div class="dates">
<div class="dates-header">Pickup & Drop-off Dates</div>
<div class="weekend">Weekend 1: Saturday, January 3 & Sunday, January 4</div>
<div class="weekend">Weekend 2: Saturday, January 10 & Sunday, January 11</div>
</div>
<div class="section">
<h2>📱 Recommended: Schedule Online Pickup</h2>
<div class="highlight-box">
<p><strong>We encourage you to use our new online scheduling system!</strong></p>
<p>It's quick, easy, and helps us plan our routes efficiently.</p>
</div>
<ol class="steps">
<li><strong>Make your donation via PayPal</strong> - Click the PayPal button below and enter your name and address when prompted (suggested: $20+ per tree, $10 per wreath/swag)</li>
<li><strong>Save your PayPal confirmation code</strong> - You'll receive this after completing your donation</li>
<li><strong>Schedule your pickup</strong> - Visit our scheduling website and enter your information along with the PayPal confirmation code</li>
<li><strong>Place your tree at the curb by 12:00 noon</strong> on your selected pickup date - No need to attach anything to the tree!</li>
</ol>
<div class="center">
<a href="https://www.paypal.com/donate/?hosted_button_id=AK4YARV9T5U8U" class="button button-secondary" target="_blank">Donate via PayPal</a>
<a href="https://scout-tree-pickup-6eed1850.base44.app/" class="button" target="_blank">Schedule Pickup</a>
</div>
</div>
<div class="section">
<h2>🏠 Traditional Curbside Pickup (Without Scheduling)</h2>
<p>If you prefer not to use the online scheduling system, you can still participate:</p>
<ul>
<li>Place your tree at the curb by <strong>12:00 noon</strong> on any pickup date</li>
<li>If paying by <strong>PayPal</strong>: Write your PayPal confirmation number on the flyer and secure it in a plastic bag attached to the tree</li>
<li>If paying by <strong>check</strong>: Make payable to "POPLC" (Prince of Peace Lutheran Church) and secure it in a plastic bag attached to the tree</li>
<li>If paying by <strong>cash</strong>: Secure it in a plastic bag attached to the tree</li>
</ul>
<div class="warning">
<strong>⚠️ Important:</strong> If you received a flyer and we haven't picked up your tree by 4:00 PM, please email <strong>info.Troop618@troopmaster.email</strong> with your address, or place your tree out again on the next pickup date.
</div>
</div>
<div class="section">
<h2>🚗 Self Drop-Off Option</h2>
<p><strong>Location:</strong> <a href="https://maps.google.com/?q=Prince+of+Peace+Lutheran+Church,14175+NW+Cornell+Rd,Portland,OR+97229" target="_blank">Prince of Peace Lutheran Church<br>
14175 NW Cornell Rd, Portland, OR 97229</a></p>
<p><strong>Hours:</strong> 12:00 PM - 4:00 PM on all pickup dates (January 3, 4, 10, & 11)</p>
<p>You can drop off your tree at any time during these hours. Payment can be made via PayPal (preferred) or cash/check on-site.</p>
</div>
<div class="section">
<h2>🤝 Suggested Donations</h2>
<div class="donation-amount">
• $20 or more per tree<br>
• $10 per wreath/swag
</div>
<p>Your generous donations help support our troop's activities and adventures throughout the year!</p>
</div>
<div class="section">
<h2>📍 Pickup Area Map</h2>
<div class="warning">
<strong>⚠️ Important:</strong> We only pick up trees from the neighborhoods shown on the map below. If you are outside this area, please use our Self Drop-Off option.
</div>
<p>Check if your address is in our pickup area:</p>
<div style="margin-top: 15px;">
<iframe src="https://www.google.com/maps/d/embed?mid=1l28aBHnHC9uK50bMkaWZFNhfSsBTpjY" width="100%" height="480" style="border:0; border-radius: 5px;"></iframe>
</div>
</div>
<div class="section">
<h2>❓ Frequently Asked Questions</h2>
<div class="faq-item">
<div class="faq-question">How do I prepare my tree for pickup?</div>
<p>Remove all ornaments, lights, tinsel, and decorations. We cannot accept flocked trees. Place your tree at the curb by 12:00 noon, visible from the street (not behind a car or by the garage).</p>
</div>
<div class="faq-item">
<div class="faq-question">Why wasn't my tree picked up?</div>
<p>Make sure your tree is out by 12:00 noon and visible from the street. If using the traditional method (without scheduling), ensure the flyer with payment is securely attached and visible. If we haven't picked up your tree by 4:00 PM and you're in our pickup area, email us at info.Troop618@troopmaster.email or place your tree out on the next collection date.</p>
</div>
<div class="faq-item">
<div class="faq-question">Can you take flocked trees?</div>
<p>Sorry, we cannot accept flocked trees as they are not recyclable.</p>
</div>
<div class="faq-item">
<div class="faq-question">What if I'm not in your pickup area?</div>
<p>You can drop off your tree at Prince of Peace Lutheran Church during our drop-off hours (12:00 PM - 4:00 PM on January 3, 4, 10, & 11).</p>
</div>
<div class="faq-item">
<div class="faq-question">Do I need to use the scheduling website?</div>
<p>No, it's optional but highly encouraged! The scheduling system helps us plan efficient routes and ensures we don't miss your tree. However, you can still use the traditional method of placing your tree at the curb with payment attached.</p>
</div>
<div class="faq-item">
<div class="faq-question">What payment methods do you accept?</div>
<p>We accept PayPal (preferred), checks payable to "POPLC", and cash. If using the online scheduling system, you must pay via PayPal before scheduling.</p>
</div>
</div>
<div class="section center">
<h2>Thank you for supporting Scout Troop 5618 & 618!</h2>
<p>Your donations help fund our camping trips, community service projects, and leadership development activities.</p>
<p style="margin-top: 20px;"><strong>Interested in joining our troop?</strong><br>
We welcome youth ages 11-17 (all genders). <a href="https://www.troop618.org">Learn more about our troop</a> or contact us at <strong>info.Troop618@troopmaster.email</strong></p>
</div>
</body>
</html>

17
wrangler.toml Normal file
View file

@ -0,0 +1,17 @@
name = "troop618"
account_id = "c7221b4e158b0c8f6009a627d5a6a41d"
compatibility_date = "2025-11-25"
main = "src/index.js"
routes = [
{ pattern = "troop618.org/*", zone_id = "62922e2b7c3bb7baee2d472943cfd594" },
{ pattern = "*.troop618.org/*", zone_id = "62922e2b7c3bb7baee2d472943cfd594" }
]
[vars]
TMSITEID = "203232"
TMSITENAME = "Troop618"
[assets]
directory = "./static"
binding = "ASSETS"