From ea7bd031cf080cae82ffefc677695e8f9b925c3c Mon Sep 17 00:00:00 2001 From: Glenn Date: Sat, 17 Aug 2024 13:29:15 -0500 Subject: [PATCH 01/21] Added migration for letter_templates table --- ...817143934_create_letter_templates_table.js | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 server/db/migrations/20240817143934_create_letter_templates_table.js diff --git a/server/db/migrations/20240817143934_create_letter_templates_table.js b/server/db/migrations/20240817143934_create_letter_templates_table.js new file mode 100644 index 000000000..80e345d85 --- /dev/null +++ b/server/db/migrations/20240817143934_create_letter_templates_table.js @@ -0,0 +1,25 @@ +module.exports = { + async up(knex) { + await knex.schema.createTable('letter_templates', (table) => { + table.increments() + table.timestamps() + table.string('lob_template_id') + table.string('sendgrid_template_id') + table.jsonb('merge_variables') + }) + + await knex.schema.alterTable('letters', (table) => { + table.string('lob_template_id') + table.string('sendgrid_template_id') + }) + }, + + async down(knex) { + await knex.schema.dropTable('letter_templates') + + await knex.schema.alterTable('letters', (table) => { + table.dropColumn('lob_template_id') + table.dropColumn('sendgrid_template_id') + }) + } +} From fa3dcb6c037dc3e17d57acf66de867401be98cc4 Mon Sep 17 00:00:00 2001 From: Glenn Date: Sat, 17 Aug 2024 19:30:19 -0500 Subject: [PATCH 02/21] Updated models Added new seeder Updated seeder files to have an ordering so references work as expected --- ...817143934_create_letter_templates_table.js | 21 +- server/db/models/campaign.js | 3 +- server/db/models/letter-template.js | 22 + server/db/models/letter.js | 4 +- .../01-seed-letter_templates-table.js | 16 + .../development/02-seed-campaigns-table.js | 394 ++++++++++++++++ ...dmins-table.js => 03-seed-admins-table.js} | 0 ...table.js => 04-seed-constituents-table.js} | 0 ...table.js => 05-seed-transactions-table.js} | 0 .../seeds/development/seed-campaigns-table.js | 425 ------------------ 10 files changed, 452 insertions(+), 433 deletions(-) create mode 100644 server/db/models/letter-template.js create mode 100644 server/db/seeds/development/01-seed-letter_templates-table.js create mode 100644 server/db/seeds/development/02-seed-campaigns-table.js rename server/db/seeds/development/{seed-admins-table.js => 03-seed-admins-table.js} (100%) rename server/db/seeds/development/{seed-constituents-table.js => 04-seed-constituents-table.js} (100%) rename server/db/seeds/development/{seed-transactions-table.js => 05-seed-transactions-table.js} (100%) delete mode 100644 server/db/seeds/development/seed-campaigns-table.js diff --git a/server/db/migrations/20240817143934_create_letter_templates_table.js b/server/db/migrations/20240817143934_create_letter_templates_table.js index 80e345d85..eb41035a8 100644 --- a/server/db/migrations/20240817143934_create_letter_templates_table.js +++ b/server/db/migrations/20240817143934_create_letter_templates_table.js @@ -2,15 +2,20 @@ module.exports = { async up(knex) { await knex.schema.createTable('letter_templates', (table) => { table.increments() - table.timestamps() - table.string('lob_template_id') - table.string('sendgrid_template_id') - table.jsonb('merge_variables') + table.timestamps(false, true, false) + table.string('lob_template_id').notNullable() + table.string('sendgrid_template_id').notNullable() + table.jsonb('merge_variables').notNullable() }) await knex.schema.alterTable('letters', (table) => { - table.string('lob_template_id') - table.string('sendgrid_template_id') + table.string('lob_template_id').nullable() + table.string('sendgrid_template_id').nullable() + }) + + await knex.schema.alterTable('campaigns', (table) => { + table.integer('letter_template_id').unsigned().notNullable() + table.foreign('letter_template_id').references('letter_templates.id') }) }, @@ -21,5 +26,9 @@ module.exports = { table.dropColumn('lob_template_id') table.dropColumn('sendgrid_template_id') }) + + await knex.schema.alterTable('campaigns', (table) => { + table.dropColumn('letter_template_id') + }) } } diff --git a/server/db/models/campaign.js b/server/db/models/campaign.js index 1b1ccd244..cf75fe676 100644 --- a/server/db/models/campaign.js +++ b/server/db/models/campaign.js @@ -25,7 +25,8 @@ class Campaign extends BaseModel { page_url: { type: 'string', minLength: 1 }, campaign_tagline: { type: 'string' }, campaign_text: { type: 'string' }, - supplemental_text: { type: 'string' } + supplemental_text: { type: 'string' }, + letter_template_id: { type: 'integer' } } } } diff --git a/server/db/models/letter-template.js b/server/db/models/letter-template.js new file mode 100644 index 000000000..a1609608f --- /dev/null +++ b/server/db/models/letter-template.js @@ -0,0 +1,22 @@ +const BaseModel = require('./_base') + +class LetterTemplate extends BaseModel { + static get tableName() { + return 'letter_templates' + } + + static get jsonSchema() { + return { + type: 'object', + required: ['lob_template_id', 'sendgrid_template_id', 'merge_variables'], + + properties: { + lob_template_id: { type: 'string', minLength: 1, maxLength: 255 }, + sendgrid_template_id: { type: 'string', minLength: 1, maxLength: 255 }, + merge_variables: { type: 'object' } + } + } + } +} + +module.exports = LetterTemplate \ No newline at end of file diff --git a/server/db/models/letter.js b/server/db/models/letter.js index 648e4872c..038a091ea 100644 --- a/server/db/models/letter.js +++ b/server/db/models/letter.js @@ -20,7 +20,9 @@ class Letter extends BaseModel { 'zip' ], properties: { - letter_template: { type: 'string', minLength: 1, maxLength: 255 }, + letter_template: { type: 'string', minLength: 1, maxLength: 255 }, // Don't use this field now. Saving it just for compatibility + lob_template_id: { type: 'string', maxLength: 255 }, + sendgrid_template_id: { type: 'string', maxLength: 255 }, letter_version: { type: 'string', minLength: 1, maxLength: 255 }, addressee: { type: 'string', minLength: 1, maxLength: 255 }, address_line_1: { type: 'string', minLength: 1, maxLength: 255 }, diff --git a/server/db/seeds/development/01-seed-letter_templates-table.js b/server/db/seeds/development/01-seed-letter_templates-table.js new file mode 100644 index 000000000..624a9c260 --- /dev/null +++ b/server/db/seeds/development/01-seed-letter_templates-table.js @@ -0,0 +1,16 @@ +module.exports = { + async seed(knex) { + await knex('letter_templates').del() + + await knex('letter_templates').insert([ + { + id: 1, + lob_template_id: 'tmpl_4ffaf2960112b63', + sendgrid_template_id: '', + merge_variables: { + community: ['Klamath', 'Joaquin Valley', 'the Hoopa Tribe'] + } + } + ]) + } +} \ No newline at end of file diff --git a/server/db/seeds/development/02-seed-campaigns-table.js b/server/db/seeds/development/02-seed-campaigns-table.js new file mode 100644 index 000000000..f1900068f --- /dev/null +++ b/server/db/seeds/development/02-seed-campaigns-table.js @@ -0,0 +1,394 @@ +module.exports = { + async seed(knex) { + // Deletes ALL existing entries + await knex('campaigns').del() + + // Inserts seed entries + await knex('campaigns').insert([ + { + id: 1, + organization: 'M4BL', + name: 'The Breathe Act', + cause: 'Civic Rights', + type: 'Grant', + page_url: 'breatheact.org', + letter_template_id: 1 + }, + { + id: 2, + organization: 'Sunrise New York', + name: 'Climate and Community Investment Act', + cause: 'Climate Justice', + type: 'Grant', + page_url: 'climatecantwait.org', + letter_template_id: 1 + }, + { + id: 3, + organization: 'Sunrise New York', + name: 'Energy Efficiency, Equity and Jobs Assembly Bill', + cause: 'Climate Justice', + type: 'Grant', + page_url: 'climatecantwait.org', + letter_template_id: 1 + }, + { + id: 4, + organization: 'Sunrise New York', + name: 'Proposed Actions on EJ Communities', + cause: 'Climate Justice', + type: 'Grant', + page_url: 'climatecantwait.org', + letter_template_id: 1 + }, + { + id: 5, + organization: "Sogorea 'Te Land Trust", + name: "Sogorea 'Te Land Trust", + cause: 'Civic Rights', + type: 'Grant', + page_url: 'https://sogoreate-landtrust.org/', + letter_template_id: 1 + }, + { + id: 6, + organization: 'Tuolumne River Trust', + name: 'Tuolumne River Trust', + cause: 'Civic Rights', + type: 'Grant', + page_url: 'https://www.tuolumne.org/revive-the-tuolumne', + letter_template_id: 1, + campaign_tagline: 'For a Healthy and Vibrant River', + campaign_text: + '

The Tuolumne River is on the verge of ecological collapse. Historically, the River hosted well over 100,000 salmon, but in 2020 only 1,000 returned to spawn. And it’s not just about fish. Before dams were constructed to divert water to farms and urban areas, salmon transported millions of pounds of nutrients from the ocean to upland habitats, where they fueled the food web and fertilized forests and meadows. Absent those nutrients, the Tuolumne’s salmon-based ecosystem is in a state of crisis.

The main cause of the River’s demise is inadequate instream flows. In an average year, only 21% of the Tuolumne’s unimpaired flow reaches the San Joaquin River. During the recent drought, unimpaired flow averaged just 12% for five straight years. Meanwhile, more than three years’ worth of water remained impounded behind SFPUC dams, and all that water (and much more) had to be “dumped” back into the River two years later to prevent flooding downstream. The Tuolumne experienced one exceptionally good year at the expense of five terrible years.

Revive the Tuolumne aims to reverse this negative trend and restore the River. Our Let it Flow campaign advocates for higher instream flows through federal licensing of dams and by supporting the State Water Board’s update of the Bay Delta Water Quality Control Plan. Our Use It Wisely campaign promotes water conservation and alternative water supplies to reduce reliance on Tuolumne River water so that more can be made available for environmental purposes.

', + supplemental_text: + '

SFPUC water policies create unnecessary water scarcity throughout the Tuolumne watershed and skyrocketing water costs for ratepayers. These water woes are the result of dubious “science” and conservative water storage based on an SFPUC-manufactured drought plan called the Design Drought.

The Design Drought arbitrarily combines two of the worst droughts on record to create a megadrought that might occur once in 25,000 years. The Design Drought has prompted the SFPUC to create an Alternative Water Supply Plan that would double the SFPUC budget (and water rates) to produce expensive water we won’t ever need, while continuing to minimize river flows in the Tuolumne.

Low flows along the Tuolumne River harm the environment: the wild salmon population is on the brink of collapse and the scarcity of this keystone species negatively impacts riparian, delta, bay, and ocean ecosystems as well; frontline communities experience illness from toxic algae blooms and water scarcity; and Indigenous Tribes and commercial fishing communities that rely on healthy fisheries experience the collapse of lifeways and economies.

We encourage you to send a letter to the San Francisco Board of Supervisors, demanding science-backed water policies and a financially viable SFPUC budget.

Let your supervisor know that the citizens call for an independent audit of the SFPUC!

', + representatives: JSON.stringify([ + { + name: 'Connie Chan', + title: 'District 1 Supervisor', + photoUrl: + 'https://sfbos.org/sites/default/files/Connie_Chan_2023.jpg', + address_line1: '1 Dr Carlton B Goodlett Pl', + address_line2: '#244', + address_city: 'San Francisco', + address_state: 'CA', + address_zip: '94102', + address_country: 'US', + email: 'chanstaff@sfgov.org' + }, + { + name: 'Catherine Stefani', + title: 'District 2 Supervisor', + photoUrl: + 'https://sfbos.org/sites/default/files/Supervisor_Stefani_2018.jpg', + address_line1: '1 Dr Carlton B Goodlett Pl', + address_line2: '#244', + address_city: 'San Francisco', + address_state: 'CA', + address_zip: '94102', + address_country: 'US', + email: 'Catherine.Stefani@sfgov.org' + }, + { + name: 'Aaron Peskin', + title: 'District 3 Supervisor', + photoUrl: + 'https://sfbos.org/sites/default/files/Aaron_Peskin_2023.jpg', + address_line1: '1 Dr Carlton B Goodlett Pl', + address_line2: '#244', + address_city: 'San Francisco', + address_state: 'CA', + address_zip: '94102', + address_country: 'US', + email: 'Aaron.Peskin@sfgov.org' + }, + { + name: 'Joel Engardio', + title: 'District 4 Supervisor', + photoUrl: + 'https://sfbos.org/sites/default/files/Joel_Engardio_2023.jpg', + address_line1: '1 Dr Carlton B Goodlett Pl', + address_line2: '#244', + address_city: 'San Francisco', + address_state: 'CA', + address_zip: '94102', + address_country: 'US', + email: '' + }, + { + name: 'Dean Preston', + title: 'District 5 Supervisor', + photoUrl: + 'https://sfbos.org/sites/default/files/Dean_Preston_2023.jpg', + address_line1: '1 Dr Carlton B Goodlett Pl', + address_line2: '#244', + address_city: 'San Francisco', + address_state: 'CA', + address_zip: '94102', + address_country: 'US', + email: 'prestonstaff@sfgov.org' + }, + { + name: 'Matt Dorsey', + title: 'District 6 Supervisor', + photoUrl: + 'https://sfbos.org/sites/default/files/Dorsey_2022_lg.jpg', + address_line1: '1 Dr Carlton B Goodlett Pl', + address_line2: '#244', + address_city: 'San Francisco', + address_state: 'CA', + address_zip: '94102', + address_country: 'US', + email: 'DorseyStaff@sfgov.org' + }, + { + name: 'Myrna Melgar', + title: 'District 7 Supervisor', + photoUrl: + 'https://sfbos.org/sites/default/files/Myrna_Melgar_2023.jpg', + address_line1: '1 Dr Carlton B Goodlett Pl', + address_line2: '#244', + address_city: 'San Francisco', + address_state: 'CA', + address_zip: '94102', + address_country: 'US', + email: 'melgarstaff@sfgov.org' + }, + { + name: 'Rafael Mandelman', + title: 'District 8 Supervisor', + photoUrl: + 'https://sfbos.org/sites/default/files/Supervisor_Mandelman_2018.jpg', + address_line1: '1 Dr Carlton B Goodlett Pl', + address_line2: '#244', + address_city: 'San Francisco', + address_state: 'CA', + address_zip: '94102', + address_country: 'US', + email: 'mandelmanstaff@sfgov.org' + }, + { + name: 'Hillary Ronen', + title: 'District 9 Supervisor', + photoUrl: + 'https://sfbos.org/sites/default/files/Supervisor_Ronen_2019.jpg', + address_line1: '1 Dr Carlton B Goodlett Pl', + address_line2: '#244', + address_city: 'San Francisco', + address_state: 'CA', + address_zip: '94102', + address_country: 'US', + email: 'RonenStaff@sfgov.org' + }, + { + name: 'Shamann Walton', + title: 'District 10 Supervisor', + photoUrl: + 'https://sfbos.org/sites/default/files/Shamann_Walton_2023.jpg', + address_line1: '1 Dr Carlton B Goodlett Pl', + address_line2: '#244', + address_city: 'San Francisco', + address_state: 'CA', + address_zip: '94102', + address_country: 'US', + email: 'waltonstaff@sfgov.org' + }, + { + name: 'Ahsha Safai', + title: 'District 11 Supervisor', + photoUrl: + 'https://sfbos.org/sites/default/files/Ahsha_Safai_2023.jpg', + address_line1: '1 Dr Carlton B Goodlett Pl', + address_line2: '#244', + address_city: 'San Francisco', + address_state: 'CA', + address_zip: '94102', + address_country: 'US', + email: 'Ahsha.Safai@sfgov.org' + } + ]), + assets: JSON.stringify({ + campaign_logo: + 'https://images.squarespace-cdn.com/content/v1/5eebc0039b04b54b2fb0ce52/1598500758914-E5HAIIGCP0ZXKKMN2FT0/TRT+Logo-13.png?format=500w', + campaign_background: + 'https://images.squarespace-cdn.com/content/v1/5eebc0039b04b54b2fb0ce52/1610135975708-FV42Q30BPWF887M05O51/Poppies-13.jpg?format=1500w', + 'campaign-img-1': + 'https://images.squarespace-cdn.com/content/v1/5eebc0039b04b54b2fb0ce52/1609785926325-63M9MY247ORIL8ON8P5E/tuolumne-camp-960x540.jpg?format=1500w', + 'campaign-img-2': + 'https://images.squarespace-cdn.com/content/v1/5eebc0039b04b54b2fb0ce52/1592586646372-TBY3WC065NJ04KT2B38Z/000091400001.jpg?format=1500w', + 'campaign-img-3': + 'https://images.squarespace-cdn.com/content/v1/5eebc0039b04b54b2fb0ce52/1609781359705-Q5YNFL6DET5ORHW62ZU7/IMG_2249_WEBSITE+copy.jpg?format=1500w' + }) + }, + { + id: 7, + organization: 'Save California Salmon', + name: 'Save California Salmon', + cause: 'Civic Rights', + type: 'Grant', + page_url: 'https://www.californiasalmon.org/', + letter_template_id: 1, + campaign_tagline: + 'Restoring and Protecting California Salmon and Rivers for Future Generations', + campaign_text: + '

#UNDAMTHEKLAMATH

Save California Salmon (SCS) is dedicated to policy change and community advocacy for Northern California’s salmon and fish dependent people. We support the fisheries and water protection work of the local communities, and advocate effective policy change for clean water, restored fisheries and vibrant communities. We aim to help to support Tribes and the general public in engaging with public comments related to water pollution, fisheries, and beneficial use issues.

Restoration of the Klamath River does not stop with dam removal. Salmon populations are continuing to plummet throughout California, leaving Tribal communities without salmon for subsistence, and ocean fishermen without a season. Restoration of the Klamath’s tributaries, which are often dewatered for animal agriculture, is also critical. We continued to support Tribal efforts to establish both permanent and temporary emergency flows in the Scott and Shasta Rivers through the California Water Resources Control Board. In December, the board passed emergency irrigation curtailments for both rivers, and we are still pushing for permanent instream flow requirements.

We also continued to fight for Trinity River flows, which are critical to the river, and to stop fish kills in the Klamath River. The Trinity is the Klamath’s largest tributary, but it is also an artificial Sacramento River tributary that feeds the Central Valley Water Project. The federal government is working on a new Biological Opinion for Endangered Species (water operations plan) for the Central Valley and State Water Projects. We are calling for a separate, protective Biological Opinion for the Trinity River, and for flows in the Bay Delta watersheds.

We are deeply dedicated to dam removal and flow restoration in all the North State’s watersheds. We want salmon back for all Northern California Tribes, which is why we are hopeful about Pacific Gas & Electric’s (PGE) December proposal to fully decommission the Eel River Dams.

', + supplemental_text: + '

At the end of 2020 California, Oregon and Berkshire Hathaway entered a new agreement to undam the Klamath River. This decision came after almost twenty years of organizing, testifying, actions and planning from the native peoples of the Klamath basin, coastal fishermen and their allies. This year we continue our advocacy to make sure these dams come down.

', + representatives: JSON.stringify([ + { + name: 'Connie Chan', + title: 'District 1 Supervisor', + photoUrl: + 'https://sfbos.org/sites/default/files/Connie_Chan_2023.jpg', + address_line1: '1 Dr Carlton B Goodlett Pl', + address_line2: '#244', + address_city: 'San Francisco', + address_state: 'CA', + address_zip: '94102', + address_country: 'US', + email: 'chanstaff@sfgov.org' + }, + { + name: 'Catherine Stefani', + title: 'District 2 Supervisor', + photoUrl: + 'https://sfbos.org/sites/default/files/Supervisor_Stefani_2018.jpg', + address_line1: '1 Dr Carlton B Goodlett Pl', + address_line2: '#244', + address_city: 'San Francisco', + address_state: 'CA', + address_zip: '94102', + address_country: 'US', + email: 'Catherine.Stefani@sfgov.org' + }, + { + name: 'Aaron Peskin', + title: 'District 3 Supervisor', + photoUrl: + 'https://sfbos.org/sites/default/files/Aaron_Peskin_2023.jpg', + address_line1: '1 Dr Carlton B Goodlett Pl', + address_line2: '#244', + address_city: 'San Francisco', + address_state: 'CA', + address_zip: '94102', + address_country: 'US', + email: 'Aaron.Peskin@sfgov.org' + }, + { + name: 'Joel Engardio', + title: 'District 4 Supervisor', + photoUrl: + 'https://sfbos.org/sites/default/files/Joel_Engardio_2023.jpg', + address_line1: '1 Dr Carlton B Goodlett Pl', + address_line2: '#244', + address_city: 'San Francisco', + address_state: 'CA', + address_zip: '94102', + address_country: 'US', + email: '' + }, + { + name: 'Dean Preston', + title: 'District 5 Supervisor', + photoUrl: + 'https://sfbos.org/sites/default/files/Dean_Preston_2023.jpg', + address_line1: '1 Dr Carlton B Goodlett Pl', + address_line2: '#244', + address_city: 'San Francisco', + address_state: 'CA', + address_zip: '94102', + address_country: 'US', + email: 'prestonstaff@sfgov.org' + }, + { + name: 'Matt Dorsey', + title: 'District 6 Supervisor', + photoUrl: + 'https://sfbos.org/sites/default/files/Dorsey_2022_lg.jpg', + address_line1: '1 Dr Carlton B Goodlett Pl', + address_line2: '#244', + address_city: 'San Francisco', + address_state: 'CA', + address_zip: '94102', + address_country: 'US', + email: 'DorseyStaff@sfgov.org' + }, + { + name: 'Myrna Melgar', + title: 'District 7 Supervisor', + photoUrl: + 'https://sfbos.org/sites/default/files/Myrna_Melgar_2023.jpg', + address_line1: '1 Dr Carlton B Goodlett Pl', + address_line2: '#244', + address_city: 'San Francisco', + address_state: 'CA', + address_zip: '94102', + address_country: 'US', + email: 'melgarstaff@sfgov.org' + }, + { + name: 'Rafael Mandelman', + title: 'District 8 Supervisor', + photoUrl: + 'https://sfbos.org/sites/default/files/Supervisor_Mandelman_2018.jpg', + address_line1: '1 Dr Carlton B Goodlett Pl', + address_line2: '#244', + address_city: 'San Francisco', + address_state: 'CA', + address_zip: '94102', + address_country: 'US', + email: 'mandelmanstaff@sfgov.org' + }, + { + name: 'Hillary Ronen', + title: 'District 9 Supervisor', + photoUrl: + 'https://sfbos.org/sites/default/files/Supervisor_Ronen_2019.jpg', + address_line1: '1 Dr Carlton B Goodlett Pl', + address_line2: '#244', + address_city: 'San Francisco', + address_state: 'CA', + address_zip: '94102', + address_country: 'US', + email: 'RonenStaff@sfgov.org' + }, + { + name: 'Shamann Walton', + title: 'District 10 Supervisor', + photoUrl: + 'https://sfbos.org/sites/default/files/Shamann_Walton_2023.jpg', + address_line1: '1 Dr Carlton B Goodlett Pl', + address_line2: '#244', + address_city: 'San Francisco', + address_state: 'CA', + address_zip: '94102', + address_country: 'US', + email: 'waltonstaff@sfgov.org' + }, + { + name: 'Ahsha Safai', + title: 'District 11 Supervisor', + photoUrl: + 'https://sfbos.org/sites/default/files/Ahsha_Safai_2023.jpg', + address_line1: '1 Dr Carlton B Goodlett Pl', + address_line2: '#244', + address_city: 'San Francisco', + address_state: 'CA', + address_zip: '94102', + address_country: 'US', + email: 'Ahsha.Safai@sfgov.org' + } + ]), + assets: JSON.stringify({ + campaign_logo: + 'https://static.wixstatic.com/media/d97ff6_b61eff2e17cc4511b92752e6af420835~mv2.png/v1/fill/w_96,h_97,al_c,q_85,usm_0.66_1.00_0.01,enc_auto/White%20circle%2C%20Black%20background%20SCS%20Logo.png', + campaign_background: 'https://i.imgur.com/4OsValj.png', + 'campaign-img-1': 'https://i.imgur.com/fGMy8Wz.png', + 'campaign-img-2': 'https://i.imgur.com/toMnnE0.png', + 'campaign-img-3': 'https://i.imgur.com/wXRXDCd.png' + }) + } + ]) + } +} diff --git a/server/db/seeds/development/seed-admins-table.js b/server/db/seeds/development/03-seed-admins-table.js similarity index 100% rename from server/db/seeds/development/seed-admins-table.js rename to server/db/seeds/development/03-seed-admins-table.js diff --git a/server/db/seeds/development/seed-constituents-table.js b/server/db/seeds/development/04-seed-constituents-table.js similarity index 100% rename from server/db/seeds/development/seed-constituents-table.js rename to server/db/seeds/development/04-seed-constituents-table.js diff --git a/server/db/seeds/development/seed-transactions-table.js b/server/db/seeds/development/05-seed-transactions-table.js similarity index 100% rename from server/db/seeds/development/seed-transactions-table.js rename to server/db/seeds/development/05-seed-transactions-table.js diff --git a/server/db/seeds/development/seed-campaigns-table.js b/server/db/seeds/development/seed-campaigns-table.js deleted file mode 100644 index 7c0732b87..000000000 --- a/server/db/seeds/development/seed-campaigns-table.js +++ /dev/null @@ -1,425 +0,0 @@ -module.exports = { - async seed(knex) { - // Deletes ALL existing entries - await knex('campaigns').del() - - // Inserts seed entries - await knex('campaigns').insert([ - { - id: 1, - organization: 'White Mesa Ute Community', - name: 'White Mesa Concerned Community', - cause: 'Civic Rights', - type: 'Grant', - page_url: 'https://protectwhitemesa.org/', - campaign_tagline: 'Protecting the Ute Tribal Lands and Peoples from Radioactive Waste', - campaign_text: '

White Mesa Concerned Community is a grassroots group of concerned tribal members of the Ute Mountain Ute Tribe. We work to inform our fellow tribal members and the public about our struggle to protect our community, health, water, air, land, culture, and sacred sites from toxic and radioactive contamination from the uranium mill. We demand that the uranium mill be closed and cleaned up.

Here are some of the species that continue to be impacted by the uranium mining:

Mexican Spotted Owl (Strix occidentalis lucida): This owl is found in forested canyons and riparian zones. The tribe works to protect its habitat by managing forest resources and reducing threats such as wildfires and logging.

Southwestern Willow Flycatcher (Empidonax traillii extimus): Found in riparian areas, this bird\'s protection includes restoring native vegetation, managing water resources, and preventing habitat degradation from livestock grazing and invasive species.

Gunnison Sage-Grouse (Centrocercus minimus): The tribe participates in habitat restoration and conservation efforts for this species, including managing land use and mitigating threats like overgrazing, invasive plants, and human encroachment.

Yellow-Billed Cuckoo (Coccyzus americanus): The tribe works to conserve riparian habitats crucial for this bird by managing water flow and restoring native plant communities that provide nesting and foraging opportunities.

Colorado Pikeminnow (Ptychocheilus lucius): The tribe collaborates with state and federal agencies to protect this endangered fish by managing water quality and flow in river systems, reducing the impact of non-native species, and restoring critical habitat areas.

Bonytail Chub (Gila elegans) and Humpback Chub (Gila cypha): Both fish species benefit from the tribe\'s efforts to maintain clean and healthy river systems, which include monitoring water quality, controlling non-native species, and advocating for water management practices that support native fish populations.

', - supplemental_text: '

The White Mesa Ute Community of the Ute Mountain Ute Tribe is located between Blanding and Bluff in San Juan County in southern Utah. It is near Cedar Mesa, the Bears Ears National Monument, Valley of the Gods, the San Juan River, national parks, and many other beautiful and sacred areas.

White Mesa, however, is adjacent to the Energy Fuels’ uranium mill, the last such facility in the United States, where uranium tailings and other radioactive materials are sent for “processing” and dumping. Not only was the mill built right next to our community, but it was built right on top of hundreds of our culturally significant sites.

', - representatives: JSON.stringify([ - { - name: 'Spencer Cox', - title: 'Governor of Utah', - photoUrl: - 'https://www.nga.org/wp-content/uploads/2021/01/Governor_Cox_official_square-scaled.jpg', - address_line1: '350 N STATE ST', - address_line2: 'STE 200', - address_city: 'SALT LAKE CITY', - address_state: 'UT', - address_zip: '84114', - address_country: 'US', - email: '' - }, - { - name: 'Phil Lyman', - title: 'State Representative for District 69', - photoUrl: - 'https://le.utah.gov/images/legislator/house/LYMANP.jpg', - address_line1: '333 S MAIN ST', - address_line2: '', - address_city: 'BLANDING', - address_state: 'UT', - address_zip: '84511', - address_country: 'US', - email: '' - }, - ]), - assets: JSON.stringify({ - campaign_logo: 'https://i.imgur.com/Lc9fG1y.png', - campaign_background: 'https://i.imgur.com/WcFdL78.jpeg', - 'campaign-img-1': 'https://i.imgur.com/gpGQxZQ.jpeg', - 'campaign-img-2': 'https://i.imgur.com/5pSUR0q.jpeg', - 'campaign-img-3': 'https://i.imgur.com/0EctJWf.png' - }) - }, - { - id: 2, - organization: 'Hualapai Nation', - name: 'Protect Hakamwe', - cause: 'Civic Rights', - type: 'Grant', - page_url: 'http://instagram.com/protecthakamwe', - campaign_tagline: 'Protect Ha’kamwe’ - No Lithium Mine', - campaign_text: '

What is Ha’Kamwe’?

Ha’Kamwe’ means warm spring in the language of the Hualapai people.

Ha’Kamwe’ is fed by water naturally stored underground in volcanic rocks that seal it off from the land surface above (aka a confined volcanic aquifer). Under pressure, water flows underground along a geologic fault and emerges from the spring.

This sacred spring is a place for healing. In the words of a Hualapai elder: this is holy ground.

Where is Ha’Kamwe’?

Ha’Kamwe’ is part of Cholla Canyon Ranch in Wikieup, Arizona, where the Mojave and Sonoran deserts meet within the Big Sandy River basin. The ranch is managed by the Hualapai Tribe, while the ancestral homelands of the Hualapai people surrounding the site are currently managed by the Bureau of Land Management (BLM).

', - supplemental_text: '

Hualapai tribal members, local community members, and allies are working to prevent further exploration drilling for the Big Sandy Lithium Project that would desecrate Ha’Kamwe’ and the ancestral homelands of the Hualapai people.

', - representatives: JSON.stringify([ - { - name: 'Dr. Buu Nygren', - title: 'President of the Navajo Nation', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/photo_P_Nygren.jpg?resize=1080%2C1080&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: 'alray.nelson@navajo-nsn.gov' - }, - { - name: 'Jasmine Blackwater-Nygren', - title: 'First Lady of the Navajo Nation', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/photo_FL_Nygren-Blackwater.jpg?resize=1080%2C1080&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: 'alray.nelson@navajo-nsn.gov' - }, - { - name:"Richelle Montoya", - title:"Vice President of the Navajo Nation", - photoUrl:"https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/photo_VP_Montoya.jpg?resize=1080%2C1080&ssl=1", - address_line1:"PO Box 7440", - address_line2:"", - address_city:"Window Rock", - address_state:"AZ", - address_zip:"86515", - address_country:"US", - email:"josie.bowman@navajo-nsn.gov" - }, - { - name: 'Ethel Branch', - title: 'Department of Justice, Attorney General', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/attorney_general_Branch.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Sean McCabe', - title: 'Office of the Controller, Controller', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/controller_McCabe.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Justin Ahasteen', - title: 'Navajo Nation Washington Office, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/director_Ahasteen.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Heather Clah', - title: 'Department of Justice, Deputy Attorney General', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2024/04/dag_Clah.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Thomas Cody', - title: 'Division of Social Services, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/director_Cody.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Sherylene Yazzie', - title: 'Department of Health, Acting Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/Seal_gray_gradient.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Roy Tracy', - title: 'Department of Diné Education, Interim Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2024/04/director_Tracy.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Tony Skrelunas', - title: 'Division of Economic Development, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/director_Skrelunas.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Bobbie Ann Baldwin', - title: 'Navajo Nation Veterans Administration, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2024/04/director_Baldwin.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Shawnevan Dale', - title: 'Executive Director, Division of General Services', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/director_Dale.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Tom Platero', - title: 'Division of Transportation, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/director_Platero.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Effie Edsitty', - title: 'Office of the Navajo Tax Commission, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/director_Edsitty.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Arbin Mitchell', - title: 'Division of Community Development, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/director_Mitchell.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Sarah Slim', - title: 'Navajo-Hopi Land Commission Office, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2024/04/director_Slim_2.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'W. Mike Halona', - title: 'Division of Natural Resources, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/director_Halona.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Byron C. Shorty', - title: 'Telecommunications Regulatory Commission Office, Acting Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2024/09/director_Shorty.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Michael Anderson', - title: 'Division of Public Safety, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/director_Anderson-1.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Stephen Etsitty', - title: 'Navajo Nation Environmental Protection Agency, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/director_Etsitty.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Dominic Beyal', - title: 'Office of Management & Budget, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2024/04/director_Beyal.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Lisa Jymm', - title: 'Navajo Nation Fiscal Recovery Fund Office, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2024/03/director.Jymm_.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Reycita Toddy', - title: 'Division of Human Resources, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/Seal_gray_gradient.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - } - ]), - assets: JSON.stringify({ - campaign_logo: 'https://i.imgur.com/o3lxGJD.png', - campaign_background: 'https://i.imgur.com/qGOHdiP.jpeg', - 'campaign-img-1': 'https://i.imgur.com/h88GBNC.jpeg', - 'campaign-img-2': 'https://i.imgur.com/lcQWK6p.jpeg', - 'campaign-img-3': 'https://i.imgur.com/bnPQVOR.jpeg', - 'infographic': 'https://i.imgur.com/BJCPDCR.jpeg' - }) - }, - { - id: 3, - organization: 'Save California Salmon', - name: 'Save California Salmon', - cause: 'Civic Rights', - type: 'Grant', - page_url: 'https://www.californiasalmon.org/', - campaign_tagline: - 'Restoring and Protecting California Salmon and Rivers for Future Generations', - campaign_text: - '

#UNDAMTHEKLAMATH

Save California Salmon (SCS) is dedicated to policy change and community advocacy for Northern California’s salmon and fish dependent people. We support the fisheries and water protection work of the local communities, and advocate effective policy change for clean water, restored fisheries and vibrant communities. We aim to help to support Tribes and the general public in engaging with public comments related to water pollution, fisheries, and beneficial use issues.

Restoration of the Klamath River does not stop with dam removal. Salmon populations are continuing to plummet throughout California, leaving Tribal communities without salmon for subsistence, and ocean fishermen without a season. Restoration of the Klamath’s tributaries, which are often dewatered for animal agriculture, is also critical. We continued to support Tribal efforts to establish both permanent and temporary emergency flows in the Scott and Shasta Rivers through the California Water Resources Control Board. In December, the board passed emergency irrigation curtailments for both rivers, and we are still pushing for permanent instream flow requirements.

We also continued to fight for Trinity River flows, which are critical to the river, and to stop fish kills in the Klamath River. The Trinity is the Klamath’s largest tributary, but it is also an artificial Sacramento River tributary that feeds the Central Valley Water Project. The federal government is working on a new Biological Opinion for Endangered Species (water operations plan) for the Central Valley and State Water Projects. We are calling for a separate, protective Biological Opinion for the Trinity River, and for flows in the Bay Delta watersheds.

We are deeply dedicated to dam removal and flow restoration in all the North State’s watersheds. We want salmon back for all Northern California Tribes, which is why we are hopeful about Pacific Gas & Electric’s (PGE) December proposal to fully decommission the Eel River Dams.

', - supplemental_text: - '

At the end of 2020 California, Oregon and Berkshire Hathaway entered a new agreement to undam the Klamath River. This decision came after almost twenty years of organizing, testifying, actions and planning from the native peoples of the Klamath basin, coastal fishermen and their allies. This year we continue our advocacy to make sure these dams come down.

', - representatives: JSON.stringify([ - { - name: 'Bureau of Reclamation', - title: '', - photoUrl: - 'https://upload.wikimedia.org/wikipedia/commons/thumb/c/ca/USBR_logo_oct_2019.jpg/220px-USBR_logo_oct_2019.jpg', - address_line1: '2800 Cottage Way', - address_line2: 'Room W-2820', - address_city: 'Sacramento', - address_state: 'CA', - address_zip: '95825', - address_country: 'US', - email: '' - } - ]), - assets: JSON.stringify({ - campaign_logo: - 'https://static.wixstatic.com/media/d97ff6_b61eff2e17cc4511b92752e6af420835~mv2.png/v1/fill/w_96,h_97,al_c,q_85,usm_0.66_1.00_0.01,enc_auto/White%20circle%2C%20Black%20background%20SCS%20Logo.png', - campaign_background: 'https://i.imgur.com/4OsValj.png', - 'campaign-img-1': 'https://i.imgur.com/fGMy8Wz.png', - 'campaign-img-2': 'https://i.imgur.com/toMnnE0.png', - 'campaign-img-3': 'https://i.imgur.com/wXRXDCd.png' - }) - } - ]) - } -} From e50ae8859adc5018371e5ddcde5905710955e31a Mon Sep 17 00:00:00 2001 From: Glenn Date: Wed, 21 Aug 2024 21:33:10 -0500 Subject: [PATCH 03/21] More work on backend --- .gitignore | 1 + server/lib/lob.js | 126 ++++++++++++++++++ .../routes/api/v1/letter-templates/index.js | 31 +++++ server/routes/api/v1/v1.js | 2 + 4 files changed, 160 insertions(+) create mode 100644 server/lib/lob.js create mode 100644 server/routes/api/v1/letter-templates/index.js diff --git a/.gitignore b/.gitignore index 7c97a281e..e00b40279 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ package-lock.json .env.test .env.local .env.*.local +.env.test # Log files npm-debug.log* diff --git a/server/lib/lob.js b/server/lib/lob.js new file mode 100644 index 000000000..9c6c6fc16 --- /dev/null +++ b/server/lib/lob.js @@ -0,0 +1,126 @@ +// Wrapper for the Lob API +// We have the SDK in this project but it has incomplete functionality +// so we will use endpoints directly. +require('dotenv').config() +const axios = require('axios') + +class LobError extends Error { + constructor(message) { + super(message) + this.name = 'LobError' + } +} + +class Lob { + constructor() { + this.apiKey = process.env.LOB_API_KEY + this.lobUrl = process.env.LOB_BASE_URL + } + + // auth headers + authHeaders() { + const encodedKey = btoa(`${this.apiKey}:`) + console.log(encodedKey) + + return { + Authorization: `Basic ${encodedKey}` + } + } + + // Merges all headers + headers() { + console.log({...this.authHeaders()}) + return {...this.authHeaders()} + } + + async template(id) { + try { + const letters = await axios.get( + `${this.lobUrl}/templates/${id}`, + { + headers: this.headers() + } + ) + + return letters.data.published_version + } catch (err) { + throw new LobError(err.message) + } + } + + async send(payload) { + const data = { + to: payload.to, + from: payload.from, + file: payload.templateId, + merge_variables: payload.mergeVariables, + use_type: 'operational', + color: false + } + + try { + const response = await axios.post({ + url: `${this.lobUrl}/letters}`, + headers: this.headers(), + 'Idempotency-key': payload.uuid, + data + }) + + return response.data + } catch(err) { + throw new LobError(err.message) + } + } + + async verifyAddress(address) { + const payload = { + recipient: address.name, + primary_line: address.line1, + secondary_line: address.line2, + city: address.city, + state: address.state, + zip_code: address.zip + } + + try { + const addr = axios.post({ + url: `${this.lobUrl}/us_verifications`, + headers: this.headers(), + data: payload + }) + + return addr.data + } catch(err) { + throw new LobError(err.message) + } + } + + // Args should be the payload returned by verifyAddress() + // See https://docs.lob.com/#tag/US-Verifications/operation/us_verification + // For some reason, the parameter names are different b/w endpoints --_-- + async returnAddress(verifiedAddress) { + const payload = { + name: verifiedAddress.name, + address_line1: verifiedAddress.primary_line, + address_line2: verifiedAddress.secondary_line, + address_city: verifiedAddress.components.city, + address_state: verifiedAddress.components.state, + address_zip: verifiedAddress.components.zip_code, + } + + try { + const addr = axios.post({ + url: `${this.lobUrl}/addresses`, + headers: this.headers(), + data: payload + }) + + return addr.data + } catch(err) { + throw new LobError(err.message) + } + } +} + + +module.exports = { Lob, LobError } \ No newline at end of file diff --git a/server/routes/api/v1/letter-templates/index.js b/server/routes/api/v1/letter-templates/index.js new file mode 100644 index 000000000..5a48e9019 --- /dev/null +++ b/server/routes/api/v1/letter-templates/index.js @@ -0,0 +1,31 @@ +// Routes for getting letter templates +const express = require('express') +const LetterTemplate = require('../../../../db/models/letter-template') +const { Lob, /*LobError*/ } = require('../../../../lib/lob') + +const router = express.Router() + +router.get('/:id', async (req, res) => { + const id = req.params.id + + if (!id) return res.status(404).end() + + try { + const letterTemplate = await LetterTemplate.query().findById(id) + console.log(letterTemplate) + + // Once we get the template, we will need the html from lob and sendgrid + const lob = new Lob() + const lobTemplate = await lob.template(letterTemplate.lobTemplateId) + + letterTemplate.lobHtml = lobTemplate.html + letterTemplate.lobVersion = lobTemplate.id + + return res.status(200).json({ letterTemplate }).end() + } catch (err) { + console.error(err) + return res.status(500).end() + } +}) + +module.exports = router diff --git a/server/routes/api/v1/v1.js b/server/routes/api/v1/v1.js index a084330ab..7da5c6822 100644 --- a/server/routes/api/v1/v1.js +++ b/server/routes/api/v1/v1.js @@ -1,9 +1,11 @@ const express = require('express') const campaigns = require('./campaigns') // If the routes file is named index.js, we can omit it when we do the import instead of writing './campaigns/index'. +const letterTemplates = require('./letter-templates') const v1Router = express.Router() // Create the final piece of the url /campaigns v1Router.use('/campaigns', campaigns) +v1Router.use('/letter_templates', letterTemplates) module.exports = v1Router From 5b28ecd9b249e51f860ab723ced1701345733ece Mon Sep 17 00:00:00 2001 From: Glenn Date: Sat, 31 Aug 2024 10:30:29 -0500 Subject: [PATCH 04/21] Added new seed data for development --- .../01-seed-letter_templates-table.js | 14 +- .../development/02-seed-campaigns-table.js | 128 ++++++++++++------ 2 files changed, 98 insertions(+), 44 deletions(-) diff --git a/server/db/seeds/development/01-seed-letter_templates-table.js b/server/db/seeds/development/01-seed-letter_templates-table.js index 624a9c260..0e84cd031 100644 --- a/server/db/seeds/development/01-seed-letter_templates-table.js +++ b/server/db/seeds/development/01-seed-letter_templates-table.js @@ -5,10 +5,18 @@ module.exports = { await knex('letter_templates').insert([ { id: 1, - lob_template_id: 'tmpl_4ffaf2960112b63', - sendgrid_template_id: '', + lob_template_id: 'tmpl_51574d88e17027e', + sendgrid_template_id: 'd-6cc5d3ab3f794b6fad01d4a45006c58b', merge_variables: { - community: ['Klamath', 'Joaquin Valley', 'the Hoopa Tribe'] + communityImpact: [ + 'my family is affected by the damming of this river', + 'too many children are being forced to work at beaver malls for substandard wages' + ], + personalImpact: [ + 'I am allergic to the hardwoods used in beaver dam construction', + 'local children are being kidnapped by beavers and indoctrinated into new age beaver spirituality', + 'local children are being kidnapped by beavers and indoctrinated into late stage beaver capitalism' + ] } } ]) diff --git a/server/db/seeds/development/02-seed-campaigns-table.js b/server/db/seeds/development/02-seed-campaigns-table.js index f1900068f..9e81e134f 100644 --- a/server/db/seeds/development/02-seed-campaigns-table.js +++ b/server/db/seeds/development/02-seed-campaigns-table.js @@ -7,51 +7,97 @@ module.exports = { await knex('campaigns').insert([ { id: 1, - organization: 'M4BL', - name: 'The Breathe Act', + organization: 'BeaverHalters', + name: 'Stopping PNW Beavers', cause: 'Civic Rights', type: 'Grant', - page_url: 'breatheact.org', - letter_template_id: 1 + page_url: 'https://example.com', + letter_template_id: 1, + campaign_tagline: 'Protecting our Woodlands and Rivers from the Big Beaver Menace', + campaign_text: '

For years, Beavers in the Pacific Northwest have been getting more aggressive about damming rivers and gentrifying our beautiful rivers.

In recent years, they have started erecting large beaver shopping centers and abducting human children to use as low wage labor in their beaver malls!

With your help, we can stop the further encroachment of beavers into human habitats.

', + supplemental_text: '

Did you know that PNW beavers are also all communists? Only with your help can we turn the tide and live in freedom and prosperity.

', + representatives: JSON.stringify([ + { + name: 'Cloud Strife', + title: 'District 1 Supervisor', + photoUrl: + 'https://placehold.co/250', + address_line1: '123 Fake St.', + address_line2: 'Suite 8B', + address_city: 'Portland', + address_state: 'OR', + address_zip: '12345', + address_country: 'US', + email: 'noreply@example.com' + }, + { + name: 'Bulma', + title: 'District 2 Supervisor', + photoUrl: + 'https://placehold.co/250', + address_line1: '123 Fake St.', + address_line2: 'Suite 9B', + address_city: 'Portland', + address_state: 'OR', + address_zip: '12345', + address_country: 'US', + email: 'noreply@example.com' + }, + { + name: 'Fei Fong Wong', + title: 'District 3 Supervisor', + photoUrl: + 'https://placehold.co/250', + address_line1: '123 Fake St.', + address_line2: 'Suite 8B', + address_city: 'Portland', + address_state: 'OR', + address_zip: '12345', + address_country: 'US', + email: 'noreply@example.com' + }, + { + name: 'Buccee', + title: 'District 1 Supervisor', + photoUrl: + 'https://placehold.co/250', + address_line1: '123 Fake St.', + address_line2: 'Suite 7F', + address_city: 'Portland', + address_state: 'OR', + address_zip: '12345', + address_country: 'US', + email: 'noreply@example.com' + }, + { + name: 'Hatsune Miku', + title: 'District 1 Supervisor', + photoUrl: + 'https://preview.redd.it/bucsune-miku-v0-niqz9xavfz3d1.png?auto=webp&s=c7291ff1aa26b98cac36f9a759de823f1d294bc3', + address_line1: '123 Fake St.', + address_line2: 'Suite 8B', + address_city: 'Portland', + address_state: 'OR', + address_zip: '12345', + address_country: 'US', + email: 'noreply@example.com' + } + ]), + assets: JSON.stringify({ + campaign_logo: + 'https://placehold.co/600x400', + campaign_background: + 'https://placehold.co/1500x600', + 'campaign-img-1': + 'https://placehold.co/600x400', + 'campaign-img-2': + 'https://placehold.co/600x400', + 'campaign-img-3': + 'https://placehold.co/600x400' + }) }, { id: 2, - organization: 'Sunrise New York', - name: 'Climate and Community Investment Act', - cause: 'Climate Justice', - type: 'Grant', - page_url: 'climatecantwait.org', - letter_template_id: 1 - }, - { - id: 3, - organization: 'Sunrise New York', - name: 'Energy Efficiency, Equity and Jobs Assembly Bill', - cause: 'Climate Justice', - type: 'Grant', - page_url: 'climatecantwait.org', - letter_template_id: 1 - }, - { - id: 4, - organization: 'Sunrise New York', - name: 'Proposed Actions on EJ Communities', - cause: 'Climate Justice', - type: 'Grant', - page_url: 'climatecantwait.org', - letter_template_id: 1 - }, - { - id: 5, - organization: "Sogorea 'Te Land Trust", - name: "Sogorea 'Te Land Trust", - cause: 'Civic Rights', - type: 'Grant', - page_url: 'https://sogoreate-landtrust.org/', - letter_template_id: 1 - }, - { - id: 6, organization: 'Tuolumne River Trust', name: 'Tuolumne River Trust', cause: 'Civic Rights', @@ -222,7 +268,7 @@ module.exports = { }) }, { - id: 7, + id: 3, organization: 'Save California Salmon', name: 'Save California Salmon', cause: 'Civic Rights', From 7947f68faf6bf89f58eb938839a18375b19e940d Mon Sep 17 00:00:00 2001 From: Glenn Date: Sun, 1 Sep 2024 21:23:34 -0500 Subject: [PATCH 05/21] Added new handlebars renderer and rendering endpoint --- package-lock.json | 166 +++++++++++++++--- package.json | 3 + ...817143934_create_letter_templates_table.js | 12 +- server/db/models/letter-template.js | 4 +- .../01-seed-letter_templates-table.js | 8 +- server/lib/handlebars.js | 23 +++ server/lib/lob.js | 2 +- server/lib/sendgrid.js | 47 +++++ .../routes/api/v1/letter-templates/index.js | 34 +++- 9 files changed, 255 insertions(+), 44 deletions(-) create mode 100644 server/lib/handlebars.js create mode 100644 server/lib/sendgrid.js diff --git a/package-lock.json b/package-lock.json index d0230b0eb..54c5e331c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,8 @@ "@fortawesome/free-regular-svg-icons": "^6.2.0", "@fortawesome/free-solid-svg-icons": "^6.2.0", "@fortawesome/vue-fontawesome": "^2.0.8", + "@sendgrid/client": "^8.1.3", + "@sendgrid/mail": "^8.1.3", "@stripe/stripe-js": "^1.35.0", "@vue-stripe/vue-stripe": "^4.4.4", "axios": "^0.27.2", @@ -28,6 +30,7 @@ "express": "^4.18.1", "express-jwt": "^8.4.0", "express-rate-limit": "^6.6.0", + "handlebars": "^4.7.8", "jwks-rsa": "^2.1.4", "knex": "^2.4.2", "lob": "^6.6.3", @@ -2657,6 +2660,51 @@ "node": ">=10.13.0" } }, + "node_modules/@sendgrid/client": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-8.1.3.tgz", + "integrity": "sha512-mRwTticRZIdUTsnyzvlK6dMu3jni9ci9J+dW/6fMMFpGRAJdCJlivFVYQvqk8kRS3RnFzS7sf6BSmhLl1ldDhA==", + "dependencies": { + "@sendgrid/helpers": "^8.0.0", + "axios": "^1.6.8" + }, + "engines": { + "node": ">=12.*" + } + }, + "node_modules/@sendgrid/client/node_modules/axios": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/@sendgrid/helpers": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-8.0.0.tgz", + "integrity": "sha512-Ze7WuW2Xzy5GT5WRx+yEv89fsg/pgy3T1E3FS0QEx0/VvRmigMZ5qyVGhJz4SxomegDkzXv/i0aFPpHKN8qdAA==", + "dependencies": { + "deepmerge": "^4.2.2" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@sendgrid/mail": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/@sendgrid/mail/-/mail-8.1.3.tgz", + "integrity": "sha512-Wg5iKSUOER83/cfY6rbPa+o3ChnYzWwv1OcsR8gCV8SKi+sUPIMroildimlnb72DBkQxcbylxng1W7f0RIX7MQ==", + "dependencies": { + "@sendgrid/client": "^8.1.3", + "@sendgrid/helpers": "^8.0.0" + }, + "engines": { + "node": ">=12.*" + } + }, "node_modules/@sideway/address": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", @@ -7469,7 +7517,6 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -9310,9 +9357,9 @@ "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" }, "node_modules/follow-redirects": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", - "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "funding": [ { "type": "individual", @@ -9738,6 +9785,26 @@ "dev": true, "license": "MIT" }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, "node_modules/har-schema": { "version": "2.0.0", "license": "ISC", @@ -12865,8 +12932,7 @@ "node_modules/minimist": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "node_modules/minipass": { "version": "3.1.6", @@ -13094,7 +13160,6 @@ }, "node_modules/neo-async": { "version": "2.6.2", - "dev": true, "license": "MIT" }, "node_modules/nice-try": { @@ -16296,7 +16361,6 @@ }, "node_modules/source-map": { "version": "0.6.1", - "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -17723,7 +17787,7 @@ }, "node_modules/uglify-js": { "version": "3.4.10", - "dev": true, + "devOptional": true, "license": "BSD-2-Clause", "dependencies": { "commander": "~2.19.0", @@ -17738,7 +17802,7 @@ }, "node_modules/uglify-js/node_modules/commander": { "version": "2.19.0", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/unbox-primitive": { @@ -19767,6 +19831,11 @@ "node": ">=0.10.0" } }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" + }, "node_modules/workbox-background-sync": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-4.3.1.tgz", @@ -21936,6 +22005,44 @@ "@panva/asn1.js": { "version": "1.0.0" }, + "@sendgrid/client": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-8.1.3.tgz", + "integrity": "sha512-mRwTticRZIdUTsnyzvlK6dMu3jni9ci9J+dW/6fMMFpGRAJdCJlivFVYQvqk8kRS3RnFzS7sf6BSmhLl1ldDhA==", + "requires": { + "@sendgrid/helpers": "^8.0.0", + "axios": "^1.6.8" + }, + "dependencies": { + "axios": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "requires": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + } + } + }, + "@sendgrid/helpers": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-8.0.0.tgz", + "integrity": "sha512-Ze7WuW2Xzy5GT5WRx+yEv89fsg/pgy3T1E3FS0QEx0/VvRmigMZ5qyVGhJz4SxomegDkzXv/i0aFPpHKN8qdAA==", + "requires": { + "deepmerge": "^4.2.2" + } + }, + "@sendgrid/mail": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/@sendgrid/mail/-/mail-8.1.3.tgz", + "integrity": "sha512-Wg5iKSUOER83/cfY6rbPa+o3ChnYzWwv1OcsR8gCV8SKi+sUPIMroildimlnb72DBkQxcbylxng1W7f0RIX7MQ==", + "requires": { + "@sendgrid/client": "^8.1.3", + "@sendgrid/helpers": "^8.0.0" + } + }, "@sideway/address": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", @@ -25568,8 +25675,7 @@ "deepmerge": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" }, "default-gateway": { "version": "5.0.5", @@ -26916,9 +27022,9 @@ "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" }, "follow-redirects": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", - "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==" + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==" }, "for-in": { "version": "1.0.2", @@ -27218,6 +27324,18 @@ "version": "2.0.1", "dev": true }, + "handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + } + }, "har-schema": { "version": "2.0.0" }, @@ -29405,8 +29523,7 @@ "minimist": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "minipass": { "version": "3.1.6", @@ -29585,8 +29702,7 @@ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, "neo-async": { - "version": "2.6.2", - "dev": true + "version": "2.6.2" }, "nice-try": { "version": "1.0.5", @@ -31888,8 +32004,7 @@ "dev": true }, "source-map": { - "version": "0.6.1", - "dev": true + "version": "0.6.1" }, "source-map-js": { "version": "1.0.2", @@ -32938,7 +33053,7 @@ }, "uglify-js": { "version": "3.4.10", - "dev": true, + "devOptional": true, "requires": { "commander": "~2.19.0", "source-map": "~0.6.1" @@ -32946,7 +33061,7 @@ "dependencies": { "commander": { "version": "2.19.0", - "dev": true + "devOptional": true } } }, @@ -34412,6 +34527,11 @@ "version": "1.2.3", "dev": true }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" + }, "workbox-background-sync": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-4.3.1.tgz", diff --git a/package.json b/package.json index 3266929c5..93dce1b94 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,8 @@ "@fortawesome/free-regular-svg-icons": "^6.2.0", "@fortawesome/free-solid-svg-icons": "^6.2.0", "@fortawesome/vue-fontawesome": "^2.0.8", + "@sendgrid/client": "^8.1.3", + "@sendgrid/mail": "^8.1.3", "@stripe/stripe-js": "^1.35.0", "@vue-stripe/vue-stripe": "^4.4.4", "axios": "^0.27.2", @@ -60,6 +62,7 @@ "express": "^4.18.1", "express-jwt": "^8.4.0", "express-rate-limit": "^6.6.0", + "handlebars": "^4.7.8", "jwks-rsa": "^2.1.4", "knex": "^2.4.2", "lob": "^6.6.3", diff --git a/server/db/migrations/20240817143934_create_letter_templates_table.js b/server/db/migrations/20240817143934_create_letter_templates_table.js index eb41035a8..03016dbe8 100644 --- a/server/db/migrations/20240817143934_create_letter_templates_table.js +++ b/server/db/migrations/20240817143934_create_letter_templates_table.js @@ -3,14 +3,15 @@ module.exports = { await knex.schema.createTable('letter_templates', (table) => { table.increments() table.timestamps(false, true, false) - table.string('lob_template_id').notNullable() - table.string('sendgrid_template_id').notNullable() + table.string('name').notNullable() + table.string('subject').notNullable() + table.text('html').notNullable() table.jsonb('merge_variables').notNullable() }) await knex.schema.alterTable('letters', (table) => { - table.string('lob_template_id').nullable() - table.string('sendgrid_template_id').nullable() + table.integer('letter_template_id').unsigned().notNullable() + table.foreign('letter_template_id').references('letter_templates.id') }) await knex.schema.alterTable('campaigns', (table) => { @@ -23,8 +24,7 @@ module.exports = { await knex.schema.dropTable('letter_templates') await knex.schema.alterTable('letters', (table) => { - table.dropColumn('lob_template_id') - table.dropColumn('sendgrid_template_id') + table.dropColumn('letter_template_id') }) await knex.schema.alterTable('campaigns', (table) => { diff --git a/server/db/models/letter-template.js b/server/db/models/letter-template.js index a1609608f..2d9a5502d 100644 --- a/server/db/models/letter-template.js +++ b/server/db/models/letter-template.js @@ -11,8 +11,8 @@ class LetterTemplate extends BaseModel { required: ['lob_template_id', 'sendgrid_template_id', 'merge_variables'], properties: { - lob_template_id: { type: 'string', minLength: 1, maxLength: 255 }, - sendgrid_template_id: { type: 'string', minLength: 1, maxLength: 255 }, + subject: { type: 'string', minLength: 1, maxLength: 255 }, + name: { type: 'string', minLength: 1, maxLength: 255 }, merge_variables: { type: 'object' } } } diff --git a/server/db/seeds/development/01-seed-letter_templates-table.js b/server/db/seeds/development/01-seed-letter_templates-table.js index 0e84cd031..90a34fcce 100644 --- a/server/db/seeds/development/01-seed-letter_templates-table.js +++ b/server/db/seeds/development/01-seed-letter_templates-table.js @@ -5,9 +5,10 @@ module.exports = { await knex('letter_templates').insert([ { id: 1, - lob_template_id: 'tmpl_51574d88e17027e', - sendgrid_template_id: 'd-6cc5d3ab3f794b6fad01d4a45006c58b', + name: 'test_template', + subject: 'To Whom it May Concern', merge_variables: { + representativeName: '', communityImpact: [ 'my family is affected by the damming of this river', 'too many children are being forced to work at beaver malls for substandard wages' @@ -17,7 +18,8 @@ module.exports = { 'local children are being kidnapped by beavers and indoctrinated into new age beaver spirituality', 'local children are being kidnapped by beavers and indoctrinated into late stage beaver capitalism' ] - } + }, + html: '

This is a test template!

Dear {{representativeName}},

This campaign is important because {{communityImpact}}.

It affects me personally because {{personalImpact}}.

' } ]) } diff --git a/server/lib/handlebars.js b/server/lib/handlebars.js new file mode 100644 index 000000000..edd3601de --- /dev/null +++ b/server/lib/handlebars.js @@ -0,0 +1,23 @@ +// Wrapper for Handlebars template engine +const handlebars = require('handlebars') + +class HandlebarsError extends Error { + constructor(message) { + super(message) + this.name = 'HandlebarsError' + } +} + +class Handlebars { + static render(mergeVariables, html) { + try { + const template = handlebars.compile(html) + + return template(mergeVariables) + } catch (err) { + throw new HandlebarsError(err.message) + } + } +} + +module.exports = Handlebars \ No newline at end of file diff --git a/server/lib/lob.js b/server/lib/lob.js index 9c6c6fc16..cd9f393f0 100644 --- a/server/lib/lob.js +++ b/server/lib/lob.js @@ -15,6 +15,7 @@ class Lob { constructor() { this.apiKey = process.env.LOB_API_KEY this.lobUrl = process.env.LOB_BASE_URL + this.env = process.env.NODE_ENV } // auth headers @@ -29,7 +30,6 @@ class Lob { // Merges all headers headers() { - console.log({...this.authHeaders()}) return {...this.authHeaders()} } diff --git a/server/lib/sendgrid.js b/server/lib/sendgrid.js new file mode 100644 index 000000000..bfd88a52f --- /dev/null +++ b/server/lib/sendgrid.js @@ -0,0 +1,47 @@ +// Wrapper for Sendgrid API + +require('dotenv').config() +const sgMail = require('@sendgrid/mail') // For sending email +const sgClient = require('@sendgrid/client') // For other api endpoints + +class SendgridError extends Error { + constructor(message) { + super(message) + this.name = SendgridError + } +} + +class Sendgrid { + constructor() { + this.apiKey = process.env.SENDGRID_API_KEY + this.env = process.env.NODE_ENV + + this.sgMail = sgMail + this.sgClient = sgClient + this.sgMail.setApiKey(this.apiKey) + this.sgClient.setApiKey(this.apiKey) + } + + async template(id) { + const params = { method: 'GET', url: `/v3/templates/${id}`} + + try { + const response = await this.sgClient.request(params) + + console.log(response) + return response + } catch (err) { + throw new SendgridError(err.message) + } + } + + async send(payload) { + if (this.env != 'production') { + return { response: 200, payload } + } + + + } +} + +module.exports = { Sendgrid, SendgridError} \ No newline at end of file diff --git a/server/routes/api/v1/letter-templates/index.js b/server/routes/api/v1/letter-templates/index.js index 5a48e9019..2de2e2eb9 100644 --- a/server/routes/api/v1/letter-templates/index.js +++ b/server/routes/api/v1/letter-templates/index.js @@ -1,7 +1,7 @@ // Routes for getting letter templates const express = require('express') const LetterTemplate = require('../../../../db/models/letter-template') -const { Lob, /*LobError*/ } = require('../../../../lib/lob') +const Handlebars = require('../../../../lib/handlebars') const router = express.Router() @@ -12,14 +12,10 @@ router.get('/:id', async (req, res) => { try { const letterTemplate = await LetterTemplate.query().findById(id) - console.log(letterTemplate) - - // Once we get the template, we will need the html from lob and sendgrid - const lob = new Lob() - const lobTemplate = await lob.template(letterTemplate.lobTemplateId) - - letterTemplate.lobHtml = lobTemplate.html - letterTemplate.lobVersion = lobTemplate.id + + if (!letterTemplate) { + return res.status(404).end() + } return res.status(200).json({ letterTemplate }).end() } catch (err) { @@ -28,4 +24,24 @@ router.get('/:id', async (req, res) => { } }) +router.post('/render', async (req, res) => { + // Takes mergeVariables payload, letterTemplate id + + const { mergeVariables, templateId } = req.body + + try { + const template = await LetterTemplate.query().findById(templateId) + + if (!template) { + return res.status(404).json({ error: 'Template id does not exist' }) + } + + const letter = Handlebars.render(mergeVariables, template.html) + + return res.status(200).json({ letter }) + } catch (err) { + return res.status(500).end() + } +}) + module.exports = router From beafe0bfa0ae30c82bde6d9a9ea8f051804eab37 Mon Sep 17 00:00:00 2001 From: Glenn Date: Tue, 3 Sep 2024 17:41:40 -0500 Subject: [PATCH 06/21] More work on rendering --- server/lib/lob.js | 5 + server/lib/sendgrid.js | 2 +- .../routes/api/v1/letter-templates/index.js | 10 +- src/components/LetterLoad.vue | 93 +++++++++---------- src/components/SearchReps.vue | 13 +-- src/components/TakeAction.vue | 37 +------- src/store/index.js | 20 +++- src/views/Home.vue | 9 +- 8 files changed, 83 insertions(+), 106 deletions(-) diff --git a/server/lib/lob.js b/server/lib/lob.js index cd9f393f0..abd0257ab 100644 --- a/server/lib/lob.js +++ b/server/lib/lob.js @@ -59,6 +59,11 @@ class Lob { } try { + if (this.env != 'production') { + return { response: 200, payload } + } + + const response = await axios.post({ url: `${this.lobUrl}/letters}`, headers: this.headers(), diff --git a/server/lib/sendgrid.js b/server/lib/sendgrid.js index bfd88a52f..89ce96e3b 100644 --- a/server/lib/sendgrid.js +++ b/server/lib/sendgrid.js @@ -7,7 +7,7 @@ const sgClient = require('@sendgrid/client') // For other api endpoints class SendgridError extends Error { constructor(message) { super(message) - this.name = SendgridError + this.name = 'SendgridError' } } diff --git a/server/routes/api/v1/letter-templates/index.js b/server/routes/api/v1/letter-templates/index.js index 2de2e2eb9..5c863de29 100644 --- a/server/routes/api/v1/letter-templates/index.js +++ b/server/routes/api/v1/letter-templates/index.js @@ -5,6 +5,9 @@ const Handlebars = require('../../../../lib/handlebars') const router = express.Router() +/** + * Retrieves a letterTemplate, given its as a query param id + */ router.get('/:id', async (req, res) => { const id = req.params.id @@ -24,9 +27,12 @@ router.get('/:id', async (req, res) => { } }) +/** + * @params mergeVariables - object + * @params id - number, string + * Renders a template + */ router.post('/render', async (req, res) => { - // Takes mergeVariables payload, letterTemplate id - const { mergeVariables, templateId } = req.body try { diff --git a/src/components/LetterLoad.vue b/src/components/LetterLoad.vue index 1ee80de63..ced79a62c 100644 --- a/src/components/LetterLoad.vue +++ b/src/components/LetterLoad.vue @@ -23,32 +23,17 @@ {{ formattedCityState }} - - Dear {{ selectedRep.name }}, - - - - - - +
+

{{ user.name }}

@@ -74,6 +59,11 @@ diff --git a/src/components/SearchReps.vue b/src/components/SearchReps.vue index c463d0a85..51286830e 100644 --- a/src/components/SearchReps.vue +++ b/src/components/SearchReps.vue @@ -231,6 +231,9 @@ export default { 'loadSingleCampaign', process.env.VUE_APP_FEATURED_CAMPAIGN ) + .then(() => { + this.$store.dispatch('loadLetterTemplate') + }) this.$store.commit('setGenericValue', { key: 'letterId', @@ -252,15 +255,7 @@ export default { clearSelectedRep() { this.$store.commit('setGenericValue', { key: 'selectedRep', value: {} }) }, - async loadLetterWorkflow() { - const letter = await axios.get(`/api/lob/templates/${this.letterId}`) - - const latest = letter.data.versions[letter.data.versions.length - 1] - - this.$store.commit('setGenericValue', { key: 'letterId', value: latest }) - - this.letterBody = latest.html - + loadLetterWorkflow() { this.listVisible = true }, CheckInputContent: function () { diff --git a/src/components/TakeAction.vue b/src/components/TakeAction.vue index a2f89952e..cda9dbd83 100644 --- a/src/components/TakeAction.vue +++ b/src/components/TakeAction.vue @@ -28,28 +28,7 @@ - - - - - - + From 4a30a9b77fc92bba7ca75b1a9ea94a3af30daff6 Mon Sep 17 00:00:00 2001 From: Glenn Date: Mon, 16 Dec 2024 21:54:54 -0600 Subject: [PATCH 11/21] formatting --- script/send-letters.js | 13 +-- script/stringify.js | 27 +++--- ...817143934_create_letter_templates_table.js | 10 +- server/db/models/letter-template.js | 2 +- .../01-seed-letter_templates-table.js | 4 +- .../development/02-seed-campaigns-table.js | 36 +++---- server/lib/handlebars.js | 2 +- server/lib/lob.js | 27 +++--- server/lib/sendgrid.js | 8 +- server/routes/api/checkout.js | 38 +++++--- src/components/HakamweLetterLoad.vue | 93 ++++++++++++++++--- src/components/LetterLoad.vue | 6 +- src/components/SearchReps.vue | 6 +- src/components/TakeAction.vue | 3 +- src/store/index.js | 7 +- src/views/Home.vue | 4 +- 16 files changed, 178 insertions(+), 108 deletions(-) diff --git a/script/send-letters.js b/script/send-letters.js index 91d711621..cf0a22b36 100644 --- a/script/send-letters.js +++ b/script/send-letters.js @@ -1,19 +1,20 @@ -const axios = require('axios'); -const letterData = require('./catchup.js'); +const axios = require('axios') +const letterData = require('./catchup.js') -(async () => { +;(async () => { const data = JSON.parse(letterData) for (const transaction of data) { try { - const response = await axios.post('https://amplify-hooks-0194518485a8.herokuapp.com/api/checkout/process-transaction', + const response = await axios.post( + 'https://amplify-hooks-0194518485a8.herokuapp.com/api/checkout/process-transaction', { data: { object: { id: transaction.stripe_id } }, - type: "payment_intent.succeeded" + type: 'payment_intent.succeeded' } ) @@ -22,4 +23,4 @@ const letterData = require('./catchup.js'); console.error(error) } } -})(); +})() diff --git a/script/stringify.js b/script/stringify.js index 2c36f5fb5..6a5046bd1 100644 --- a/script/stringify.js +++ b/script/stringify.js @@ -26,16 +26,17 @@ const reps = JSON.stringify([ email: 'alray.nelson@navajo-nsn.gov' }, { - name:"Richelle Montoya", - title:"Vice President of the Navajo Nation", - photoUrl:"https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/photo_VP_Montoya.jpg?resize=1080%2C1080&ssl=1", - address_line1:"PO Box 7440", - address_line2:"", - address_city:"Window Rock", - address_state:"AZ", - address_zip:"86515", - address_country:"US", - email:"josie.bowman@navajo-nsn.gov" + name: 'Richelle Montoya', + title: 'Vice President of the Navajo Nation', + photoUrl: + 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/photo_VP_Montoya.jpg?resize=1080%2C1080&ssl=1', + address_line1: 'PO Box 7440', + address_line2: '', + address_city: 'Window Rock', + address_state: 'AZ', + address_zip: '86515', + address_country: 'US', + email: 'josie.bowman@navajo-nsn.gov' }, { name: 'Ethel Branch', @@ -234,7 +235,8 @@ const reps = JSON.stringify([ }, { name: 'Byron C. Shorty', - title: 'Telecommunications Regulatory Commission Office, Acting Executive Director', + title: + 'Telecommunications Regulatory Commission Office, Acting Executive Director', photoUrl: 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2024/09/director_Shorty.jpg?resize=1080%2C1440&ssl=1', address_line1: 'PO Box 7440', @@ -309,10 +311,9 @@ const reps = JSON.stringify([ address_zip: '86515', address_country: 'US', email: '' - } + } ]) - /* const assets = JSON.stringify({ campaign_logo: 'https://i.imgur.com/o3lxGJD.png', diff --git a/server/db/migrations/20240817143934_create_letter_templates_table.js b/server/db/migrations/20240817143934_create_letter_templates_table.js index 56d271f13..d575ff056 100644 --- a/server/db/migrations/20240817143934_create_letter_templates_table.js +++ b/server/db/migrations/20240817143934_create_letter_templates_table.js @@ -12,10 +12,12 @@ module.exports = { await knex.schema.alterTable('letters', (table) => { table.integer('letter_template_id').unsigned().notNullable() table.foreign('letter_template_id').references('letter_templates.id') - table.enu('delivery_method', ['email', 'snail_mail'], { - useNative: true, - enumName: 'delivery_methods' - }).notNullable() + table + .enu('delivery_method', ['email', 'snail_mail'], { + useNative: true, + enumName: 'delivery_methods' + }) + .notNullable() table.string('email') }) diff --git a/server/db/models/letter-template.js b/server/db/models/letter-template.js index 2d9a5502d..4c1b32128 100644 --- a/server/db/models/letter-template.js +++ b/server/db/models/letter-template.js @@ -19,4 +19,4 @@ class LetterTemplate extends BaseModel { } } -module.exports = LetterTemplate \ No newline at end of file +module.exports = LetterTemplate diff --git a/server/db/seeds/development/01-seed-letter_templates-table.js b/server/db/seeds/development/01-seed-letter_templates-table.js index 12832f8ea..550747351 100644 --- a/server/db/seeds/development/01-seed-letter_templates-table.js +++ b/server/db/seeds/development/01-seed-letter_templates-table.js @@ -1,7 +1,7 @@ module.exports = { async seed(knex) { await knex('letter_templates').del() - + await knex('letter_templates').insert([ { id: 1, @@ -35,4 +35,4 @@ module.exports = { } ]) } -} \ No newline at end of file +} diff --git a/server/db/seeds/development/02-seed-campaigns-table.js b/server/db/seeds/development/02-seed-campaigns-table.js index 2dc5092e7..363289c8a 100644 --- a/server/db/seeds/development/02-seed-campaigns-table.js +++ b/server/db/seeds/development/02-seed-campaigns-table.js @@ -13,15 +13,17 @@ module.exports = { type: 'Grant', page_url: 'https://example.com', letter_template_id: 1, - campaign_tagline: 'Protecting our Woodlands and Rivers from the Big Beaver Menace', - campaign_text: '

For years, Beavers in the Pacific Northwest have been getting more aggressive about damming rivers and gentrifying our beautiful rivers.

In recent years, they have started erecting large beaver shopping centers and abducting human children to use as low wage labor in their beaver malls!

With your help, we can stop the further encroachment of beavers into human habitats.

', - supplemental_text: '

Did you know that PNW beavers are also all communists? Only with your help can we turn the tide and live in freedom and prosperity.

', + campaign_tagline: + 'Protecting our Woodlands and Rivers from the Big Beaver Menace', + campaign_text: + '

For years, Beavers in the Pacific Northwest have been getting more aggressive about damming rivers and gentrifying our beautiful rivers.

In recent years, they have started erecting large beaver shopping centers and abducting human children to use as low wage labor in their beaver malls!

With your help, we can stop the further encroachment of beavers into human habitats.

', + supplemental_text: + '

Did you know that PNW beavers are also all communists? Only with your help can we turn the tide and live in freedom and prosperity.

', representatives: JSON.stringify([ { name: 'Velma Dinkley', title: 'District 1 Supervisor', - photoUrl: - 'https://placehold.co/250', + photoUrl: 'https://placehold.co/250', address_line1: '123 Fake St.', address_line2: 'Suite 8B', address_city: 'Portland', @@ -33,8 +35,7 @@ module.exports = { { name: 'Jar Jar Binks', title: 'District 2 Supervisor', - photoUrl: - 'https://placehold.co/250', + photoUrl: 'https://placehold.co/250', address_line1: '123 Fake St.', address_line2: 'Suite 9B', address_city: 'Portland', @@ -46,8 +47,7 @@ module.exports = { { name: 'Fei Fong Wong', title: 'District 3 Supervisor', - photoUrl: - 'https://placehold.co/250', + photoUrl: 'https://placehold.co/250', address_line1: '123 Fake St.', address_line2: 'Suite 8B', address_city: 'Portland', @@ -59,8 +59,7 @@ module.exports = { { name: 'Buccee Beaver', title: 'District 1 Supervisor', - photoUrl: - 'https://placehold.co/250', + photoUrl: 'https://placehold.co/250', address_line1: '123 Fake St.', address_line2: 'Suite 7F', address_city: 'Portland', @@ -84,16 +83,11 @@ module.exports = { } ]), assets: JSON.stringify({ - campaign_logo: - 'https://placehold.co/600x400', - campaign_background: - 'https://placehold.co/1500x600', - 'campaign-img-1': - 'https://placehold.co/600x400', - 'campaign-img-2': - 'https://placehold.co/600x400', - 'campaign-img-3': - 'https://placehold.co/600x400' + campaign_logo: 'https://placehold.co/600x400', + campaign_background: 'https://placehold.co/1500x600', + 'campaign-img-1': 'https://placehold.co/600x400', + 'campaign-img-2': 'https://placehold.co/600x400', + 'campaign-img-3': 'https://placehold.co/600x400' }) }, { diff --git a/server/lib/handlebars.js b/server/lib/handlebars.js index edd3601de..6fd3ea5d4 100644 --- a/server/lib/handlebars.js +++ b/server/lib/handlebars.js @@ -20,4 +20,4 @@ class Handlebars { } } -module.exports = Handlebars \ No newline at end of file +module.exports = Handlebars diff --git a/server/lib/lob.js b/server/lib/lob.js index abd0257ab..4114b8d77 100644 --- a/server/lib/lob.js +++ b/server/lib/lob.js @@ -15,14 +15,14 @@ class Lob { constructor() { this.apiKey = process.env.LOB_API_KEY this.lobUrl = process.env.LOB_BASE_URL - this.env = process.env.NODE_ENV + this.env = process.env.NODE_ENV } // auth headers authHeaders() { const encodedKey = btoa(`${this.apiKey}:`) console.log(encodedKey) - + return { Authorization: `Basic ${encodedKey}` } @@ -30,17 +30,14 @@ class Lob { // Merges all headers headers() { - return {...this.authHeaders()} + return { ...this.authHeaders() } } async template(id) { try { - const letters = await axios.get( - `${this.lobUrl}/templates/${id}`, - { - headers: this.headers() - } - ) + const letters = await axios.get(`${this.lobUrl}/templates/${id}`, { + headers: this.headers() + }) return letters.data.published_version } catch (err) { @@ -63,7 +60,6 @@ class Lob { return { response: 200, payload } } - const response = await axios.post({ url: `${this.lobUrl}/letters}`, headers: this.headers(), @@ -72,7 +68,7 @@ class Lob { }) return response.data - } catch(err) { + } catch (err) { throw new LobError(err.message) } } @@ -95,7 +91,7 @@ class Lob { }) return addr.data - } catch(err) { + } catch (err) { throw new LobError(err.message) } } @@ -110,7 +106,7 @@ class Lob { address_line2: verifiedAddress.secondary_line, address_city: verifiedAddress.components.city, address_state: verifiedAddress.components.state, - address_zip: verifiedAddress.components.zip_code, + address_zip: verifiedAddress.components.zip_code } try { @@ -121,11 +117,10 @@ class Lob { }) return addr.data - } catch(err) { + } catch (err) { throw new LobError(err.message) } } } - -module.exports = { Lob, LobError } \ No newline at end of file +module.exports = { Lob, LobError } diff --git a/server/lib/sendgrid.js b/server/lib/sendgrid.js index 89ce96e3b..f1ffd4e2f 100644 --- a/server/lib/sendgrid.js +++ b/server/lib/sendgrid.js @@ -17,13 +17,13 @@ class Sendgrid { this.env = process.env.NODE_ENV this.sgMail = sgMail - this.sgClient = sgClient + this.sgClient = sgClient this.sgMail.setApiKey(this.apiKey) this.sgClient.setApiKey(this.apiKey) } async template(id) { - const params = { method: 'GET', url: `/v3/templates/${id}`} + const params = { method: 'GET', url: `/v3/templates/${id}` } try { const response = await this.sgClient.request(params) @@ -39,9 +39,7 @@ class Sendgrid { if (this.env != 'production') { return { response: 200, payload } } - - } } -module.exports = { Sendgrid, SendgridError} \ No newline at end of file +module.exports = { Sendgrid, SendgridError } diff --git a/server/routes/api/checkout.js b/server/routes/api/checkout.js index 2c273a836..efbd255ca 100644 --- a/server/routes/api/checkout.js +++ b/server/routes/api/checkout.js @@ -56,10 +56,16 @@ router.post('/create-checkout-session', async (req, res) => { // Using a temporary mapping here also // Re-render the letter html, merging user data to be saved in case that's in the template. - letter.merge_variables = { ...letter.merge_variables, firstName: user.firstName, lastName: user.lastName } - const template = await LetterTemplate.query().findById(letter.letter_template_id) + letter.merge_variables = { + ...letter.merge_variables, + firstName: user.firstName, + lastName: user.lastName + } + const template = await LetterTemplate.query().findById( + letter.letter_template_id + ) const html = Handlebars.render(letter.merge_variables, template.html) - + // Using a temporary mapping here also for (const method of deliveryMethods) { // Generate a uuid so letters are idempotent @@ -114,10 +120,16 @@ router.post('/create-checkout-session', async (req, res) => { }) // Re-render the letter html, merging user data to be saved in case that's in the template. - letter.merge_variables = { ...letter.merge_variables, firstName: user.firstName, lastName: user.lastName } - const template = await LetterTemplate.query().findById(letter.letter_template_id) + letter.merge_variables = { + ...letter.merge_variables, + firstName: user.firstName, + lastName: user.lastName + } + const template = await LetterTemplate.query().findById( + letter.letter_template_id + ) const html = Handlebars.render(letter.merge_variables, template.html) - + // Using a temporary mapping here also for (const method of deliveryMethods) { // Generate a uuid so letters are idempotent @@ -188,19 +200,23 @@ router.post('/process-transaction', async (req, res) => { ) } - const transaction = await Transaction.query().findOne({ stripe_transaction_id: paymentIntent }) + const transaction = await Transaction.query().findOne({ + stripe_transaction_id: paymentIntent + }) await transaction.$query().patch({ status: eventOutcome }) - const letter = await Letter.query().where({ transaction_id: transaction.id }).first() + const letter = await Letter.query() + .where({ transaction_id: transaction.id }) + .first() letter.trackingNumber = uuidv4() const letterTemplate = JSON.parse(letter.letterTemplate) - + const lobApiKey = process.env.LOB_API_KEY const lobCredentials = btoa(`${lobApiKey}:`) console.log(letter.mergeVariables) const lobResponse = await axios.post( - 'https://api.lob.com/v1/letters', + 'https://api.lob.com/v1/letters', { to: { name: letter.addressee, @@ -226,7 +242,7 @@ router.post('/process-transaction', async (req, res) => { if (!lobResponse.statusCode === 200) throw new CheckoutError(lobResponse) - await letter.$query().patch({ sent: true}) + await letter.$query().patch({ sent: true }) return res.status(201).end() } catch (error) { diff --git a/src/components/HakamweLetterLoad.vue b/src/components/HakamweLetterLoad.vue index 33cad6b94..a204ea50f 100644 --- a/src/components/HakamweLetterLoad.vue +++ b/src/components/HakamweLetterLoad.vue @@ -12,7 +12,7 @@ {{ selectedRep.address_city }}, {{ selectedRep.address_state }}, {{ selectedRep.address_zip }} - +
{{ user.name }}
{{ user.line1 }} @@ -29,27 +29,90 @@

Hello,

-

am an Arizona constituent writing in to discuss my grave concerns regarding the ongoing drilling activities in Sandy Valley, northern Arizona.

-

1. Threats to Hualapai Cultural Heritage and Religious Freedoms

-

The mining exploration, authorized by the Bureau of Land Management (BLM), directly impacts Ha’Kamwe’ (Cofer Hot Spring), a sacred site that holds profound spiritual significance for the Hualapai Tribe and other Indigenous communities.

+

+ am an Arizona constituent writing in to discuss my grave concerns + regarding the ongoing drilling activities in Sandy Valley, northern + Arizona. +

+

+ 1. Threats to Hualapai Cultural Heritage and Religious + Freedoms +

+

+ The mining exploration, authorized by the Bureau of Land Management + (BLM), directly impacts Ha’Kamwe’ (Cofer Hot Spring), a sacred site + that holds profound spiritual significance for the Hualapai Tribe + and other Indigenous communities. +

    -
  • Religious Freedom Restoration Act (42 U.S.C. § 2000bb et seq.): The ongoing drilling undermines how the Hualapai and other tribes have used the spring for centuries for healing, prayer, and rites of passage, including childbirth and coming-of-age ceremonies for young women. Ha’Kamwe’ is integral to the spiritual practices of the Hualapai people.
  • -
  • National Historic Preservation Act (54 U.S.C. § 300101 et seq.): Ha’Kamwe’ is part of the ancient Salt Song Trail and features prominently in tribal songs and stories about the Hualapai people’s history and connection to their land. BLM’s approval of exploratory drilling without fully considering the cultural importance of Ha’Kamwe’ disregards this statute and disrespects the rights of the Hualapai Tribe.
  • +
  • + Religious Freedom Restoration Act (42 U.S.C. § 2000bb et + seq.): + The ongoing drilling undermines how the Hualapai and other tribes + have used the spring for centuries for healing, prayer, and rites + of passage, including childbirth and coming-of-age ceremonies for + young women. Ha’Kamwe’ is integral to the spiritual practices of + the Hualapai people. +
  • +
  • + National Historic Preservation Act (54 U.S.C. § 300101 et + seq.): + Ha’Kamwe’ is part of the ancient Salt Song Trail and features + prominently in tribal songs and stories about the Hualapai + people’s history and connection to their land. BLM’s approval of + exploratory drilling without fully considering the cultural + importance of Ha’Kamwe’ disregards this statute and disrespects + the rights of the Hualapai Tribe. +
-
-

2. Environmental Violations and the Rights of Nature

-

The drilling project threatens to cause irreversible damage to the local ecosystem, including the depletion of water sources that sustain Ha’Kamwe’. The proposed 131 exploration holes, reaching depths of up to 360 feet, could alter the temperature and flow of the aquifer feeding the spring, endangering the surrounding plants and wildlife.

+
+

+ 2. Environmental Violations and the Rights of Nature +

+

+ The drilling project threatens to cause irreversible damage to the + local ecosystem, including the depletion of water sources that + sustain Ha’Kamwe’. The proposed 131 exploration holes, reaching + depths of up to 360 feet, could alter the temperature and flow of + the aquifer feeding the spring, endangering the surrounding plants + and wildlife. +

    -
  • Clean Water Act (33 U.S.C. § 1251 et seq.) The drilling activities risk contaminating the aquifer, which could lead to ecological degradation, violating federal regulations designed to protect water quality.
  • -
  • Rights of Nature Doctrine: The concept of the Rights of Nature recognizes natural entities, such as springs, as rights-bearing entities with the right to exist, thrive, and regenerate. The drilling endangers Ha’Kamwe’, infringing on its right to exist and maintain its natural state.
  • +
  • + Clean Water Act (33 U.S.C. § 1251 et seq.) The + drilling activities risk contaminating the aquifer, which could + lead to ecological degradation, violating federal regulations + designed to protect water quality. +
  • +
  • + Rights of Nature Doctrine: The concept of the + Rights of Nature recognizes natural entities, such as springs, as + rights-bearing entities with the right to exist, thrive, and + regenerate. The drilling endangers Ha’Kamwe’, infringing on its + right to exist and maintain its natural state. +
-
+

Call for Collaboration and Respect:

-

We request a precautionary pause as an injunction on all drilling activities in Sandy Valley until a thorough assessment of the environmental and cultural impacts can be conducted, and meaningful consultation with the Hualapai Nation can take place.

-

We await your prompt response and look forward to scheduling a meeting at your earliest convenience.

- Sincerely, + We request a precautionary pause as an injunction on all drilling + activities in Sandy Valley until a thorough assessment of the + environmental and cultural impacts can be conducted, and meaningful + consultation with the Hualapai Nation can take place. +

+

+ We await your prompt response and look forward to scheduling a + meeting at your earliest convenience.

+

Sincerely,

{{ user.name }}

diff --git a/src/components/LetterLoad.vue b/src/components/LetterLoad.vue index 3f39b3461..e0501b66f 100644 --- a/src/components/LetterLoad.vue +++ b/src/components/LetterLoad.vue @@ -3,14 +3,14 @@
- -
+
@@ -115,7 +115,7 @@ export default { key: 'mergeVariables', value: this.userSelections }) - + this.renderLetter() }, deep: true diff --git a/src/components/SearchReps.vue b/src/components/SearchReps.vue index 51286830e..7df442fba 100644 --- a/src/components/SearchReps.vue +++ b/src/components/SearchReps.vue @@ -227,10 +227,8 @@ export default { // Duplicated to ensure that this data stays will be in Vuex if someone happens to // refresh. Should be reworked in the new repo, but needs must \_(-_-)_/ if (!this.campaignId) { - this.$store.dispatch( - 'loadSingleCampaign', - process.env.VUE_APP_FEATURED_CAMPAIGN - ) + this.$store + .dispatch('loadSingleCampaign', process.env.VUE_APP_FEATURED_CAMPAIGN) .then(() => { this.$store.dispatch('loadLetterTemplate') }) diff --git a/src/components/TakeAction.vue b/src/components/TakeAction.vue index c788f173e..172bfc7cc 100644 --- a/src/components/TakeAction.vue +++ b/src/components/TakeAction.vue @@ -147,8 +147,7 @@ export default { SignName, DonateMoney }, - props: { - }, + props: {}, data() { return { panel: 0, diff --git a/src/store/index.js b/src/store/index.js index 0c9f5577d..e5b55690a 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -19,7 +19,7 @@ export default new Vuex.Store({ campaignText: '', campaignTagline: '', supplementalText: '', - letterTemplateId: '', + letterTemplateId: '' }, representatives: [], assets: {}, @@ -129,7 +129,10 @@ export default new Vuex.Store({ const { letterTemplate } = res.data console.log(letterTemplate) - commit('setGenericValue', { key: 'letterTemplate', value: letterTemplate }) + commit('setGenericValue', { + key: 'letterTemplate', + value: letterTemplate + }) } catch (e) { alert(e) } diff --git a/src/views/Home.vue b/src/views/Home.vue index 0ba5de6a7..062852014 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -22,9 +22,9 @@ export default { // Also populates representatives and assets await this.$store.dispatch('loadSingleCampaign', campaignId) - + this.$store.dispatch('loadLetterTemplate') - + this.$store.commit('setGenericValue', { key: 'mode', value: mode }) } } From d22d96dc9288562b6636e3b256c88e4ac53748a6 Mon Sep 17 00:00:00 2001 From: Glenn Date: Mon, 16 Dec 2024 21:58:54 -0600 Subject: [PATCH 12/21] Removed orphaned
--- src/components/DonateMoney.vue | 101 +++++++++++++++++---------------- 1 file changed, 51 insertions(+), 50 deletions(-) diff --git a/src/components/DonateMoney.vue b/src/components/DonateMoney.vue index d1f3fd4bd..b474200ea 100644 --- a/src/components/DonateMoney.vue +++ b/src/components/DonateMoney.vue @@ -52,58 +52,59 @@ 2 - - 20 - - - - 50 - - - - 0 - - - - Custom Amount - - - -
- - mdi-currency-usd - {{ styledCustomDonation }} - -
+ + 20 + + + + 50 + + + + 0 + + + + Custom Amount + + + +
+ + mdi-currency-usd + {{ styledCustomDonation }} +
- Send Letter + + Send Letter +
@@ -234,7 +235,7 @@ export default { 'dumpStateToLocalStorage', response.data.sessionId ) - + location.href = response.data.url }) .catch((error) => { From e652fd5ca39f724b98917ce84d550de5e84fba56 Mon Sep 17 00:00:00 2001 From: Glenn Date: Tue, 17 Dec 2024 21:01:35 -0600 Subject: [PATCH 13/21] Fixed non-nullable migration value --- .../migrations/20240817143934_create_letter_templates_table.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/db/migrations/20240817143934_create_letter_templates_table.js b/server/db/migrations/20240817143934_create_letter_templates_table.js index d575ff056..34eafa36c 100644 --- a/server/db/migrations/20240817143934_create_letter_templates_table.js +++ b/server/db/migrations/20240817143934_create_letter_templates_table.js @@ -10,7 +10,7 @@ module.exports = { }) await knex.schema.alterTable('letters', (table) => { - table.integer('letter_template_id').unsigned().notNullable() + table.integer('letter_template_id').unsigned() table.foreign('letter_template_id').references('letter_templates.id') table .enu('delivery_method', ['email', 'snail_mail'], { From f566d8271ac4c60abd42e060f1d32c18157761ef Mon Sep 17 00:00:00 2001 From: Glenn Date: Tue, 17 Dec 2024 21:07:35 -0600 Subject: [PATCH 14/21] One more non-nullable fix --- .../migrations/20240817143934_create_letter_templates_table.js | 1 - 1 file changed, 1 deletion(-) diff --git a/server/db/migrations/20240817143934_create_letter_templates_table.js b/server/db/migrations/20240817143934_create_letter_templates_table.js index 34eafa36c..e7ff1a0c4 100644 --- a/server/db/migrations/20240817143934_create_letter_templates_table.js +++ b/server/db/migrations/20240817143934_create_letter_templates_table.js @@ -17,7 +17,6 @@ module.exports = { useNative: true, enumName: 'delivery_methods' }) - .notNullable() table.string('email') }) From ca17fa3d87981cef033cb332f677af949edf411f Mon Sep 17 00:00:00 2001 From: Glenn Date: Tue, 17 Dec 2024 21:11:10 -0600 Subject: [PATCH 15/21] More fixes --- .../migrations/20240817143934_create_letter_templates_table.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/db/migrations/20240817143934_create_letter_templates_table.js b/server/db/migrations/20240817143934_create_letter_templates_table.js index e7ff1a0c4..eef599aed 100644 --- a/server/db/migrations/20240817143934_create_letter_templates_table.js +++ b/server/db/migrations/20240817143934_create_letter_templates_table.js @@ -21,7 +21,7 @@ module.exports = { }) await knex.schema.alterTable('campaigns', (table) => { - table.integer('letter_template_id').unsigned().notNullable() + table.integer('letter_template_id').unsigned() table.foreign('letter_template_id').references('letter_templates.id') }) }, From bb672b581cd7e3ac739256fb31eec7231baf69d1 Mon Sep 17 00:00:00 2001 From: Glenn Date: Tue, 17 Dec 2024 22:12:46 -0600 Subject: [PATCH 16/21] Updated seed data, some minor letter rendering changes --- .env | 6 +- .../01-seed-letter_templates-table.js | 7 + .../development/02-seed-campaigns-table.js | 358 ++---------------- src/components/LetterLoad.vue | 16 +- src/store/index.js | 2 +- 5 files changed, 54 insertions(+), 335 deletions(-) diff --git a/.env b/.env index dbcc22ed9..d1873d52e 100644 --- a/.env +++ b/.env @@ -32,12 +32,12 @@ TWILIO_AUTH_TOKEN=TWILIO_SECRET_KEY # **We always run in single-campaign mode now so this is mandatory!** # Use campaign seeder file for local dev campaigns. VUE_APP_CAMPAIGN_MODE=single -VUE_APP_FEATURED_CAMPAIGN=1 +VUE_APP_FEATURED_CAMPAIGN=2 -VUE_APP_EMPTY_TRANSACTIONS=on +VUE_APP_EMPTY_TRANSACTIONS=off VUE_APP_SHOW_EXT_DONATION=false VUE_APP_EXT_DONATION_URL= -VUE_APP_NO_COST_MAIL=true +VUE_APP_NO_COST_MAIL=false POSTGRES_USER=postgres POSTGRES_PASSWORD=postgres diff --git a/server/db/seeds/development/01-seed-letter_templates-table.js b/server/db/seeds/development/01-seed-letter_templates-table.js index 550747351..03c84e59e 100644 --- a/server/db/seeds/development/01-seed-letter_templates-table.js +++ b/server/db/seeds/development/01-seed-letter_templates-table.js @@ -32,6 +32,13 @@ module.exports = { } }, html: '

This is a test template!

Dear {{representativeName}},

This campaign is important because {{communityImpact}}.

It affects me personally because {{personalImpact}}.

' + }, + { + id: 2, + name: 'rutgers caste equity petition', + subject: 'To the Administration of Rutgers University', + merge_variables: {}, + html: '

Dear Rutgers Administration,

I write today to urge Rutgers University to take bold action by adopting all four recommendations from the University Task Force on Caste Discrimination, including adding caste as a protected category within the institution’s anti-discrimination policies. This essential step would reaffirm Rutgers’ commitment to fostering an inclusive and equitable campus for all students, faculty, and staff.

Caste discrimination is a grave and pervasive form of oppression that transcends borders and affects marginalized communities globally. At Rutgers, caste-oppressed students and staff deserve the same protections afforded to others against bias and harm. Recognizing caste explicitly in Rutgers’ policies will ensure that those impacted have the institutional support needed to seek accountability and justice.

The inclusion of caste protections is not about targeting any particular group; it is about creating an environment where equity is non-negotiable. Opponents of this policy often use misinformation to sideline the voices of caste-oppressed communities. Rutgers must not allow such narratives to delay progress. Instead, it should set a powerful example by prioritizing the voices of those most impacted and centering their lived experiences in its decision-making.

As a university that prides itself on diversity, equity, and inclusion, Rutgers has an opportunity to demonstrate what those values look like in practice. By taking immediate steps to implement the Task Force’s recommendations, Rutgers can establish itself as a leader in addressing caste oppression in higher education.

This is a pivotal moment for Rutgers to be on the right side of history. I urge you to act now and adopt caste protections, ensuring that all members of your community can thrive with dignity, safety, and equality.

In solidarity,

{{ name }}

' } ]) } diff --git a/server/db/seeds/development/02-seed-campaigns-table.js b/server/db/seeds/development/02-seed-campaigns-table.js index 363289c8a..7f021355a 100644 --- a/server/db/seeds/development/02-seed-campaigns-table.js +++ b/server/db/seeds/development/02-seed-campaigns-table.js @@ -92,341 +92,61 @@ module.exports = { }, { id: 2, - organization: 'Tuolumne River Trust', - name: 'Tuolumne River Trust', + organization: 'Equality Labs', + name: 'Protect Caste Equity at Rutgers University', cause: 'Civic Rights', type: 'Grant', - page_url: 'https://www.tuolumne.org/revive-the-tuolumne', - letter_template_id: 1, - campaign_tagline: 'For a Healthy and Vibrant River', - campaign_text: - '

The Tuolumne River is on the verge of ecological collapse. Historically, the River hosted well over 100,000 salmon, but in 2020 only 1,000 returned to spawn. And it’s not just about fish. Before dams were constructed to divert water to farms and urban areas, salmon transported millions of pounds of nutrients from the ocean to upland habitats, where they fueled the food web and fertilized forests and meadows. Absent those nutrients, the Tuolumne’s salmon-based ecosystem is in a state of crisis.

The main cause of the River’s demise is inadequate instream flows. In an average year, only 21% of the Tuolumne’s unimpaired flow reaches the San Joaquin River. During the recent drought, unimpaired flow averaged just 12% for five straight years. Meanwhile, more than three years’ worth of water remained impounded behind SFPUC dams, and all that water (and much more) had to be “dumped” back into the River two years later to prevent flooding downstream. The Tuolumne experienced one exceptionally good year at the expense of five terrible years.

Revive the Tuolumne aims to reverse this negative trend and restore the River. Our Let it Flow campaign advocates for higher instream flows through federal licensing of dams and by supporting the State Water Board’s update of the Bay Delta Water Quality Control Plan. Our Use It Wisely campaign promotes water conservation and alternative water supplies to reduce reliance on Tuolumne River water so that more can be made available for environmental purposes.

', - supplemental_text: - '

SFPUC water policies create unnecessary water scarcity throughout the Tuolumne watershed and skyrocketing water costs for ratepayers. These water woes are the result of dubious “science” and conservative water storage based on an SFPUC-manufactured drought plan called the Design Drought.

The Design Drought arbitrarily combines two of the worst droughts on record to create a megadrought that might occur once in 25,000 years. The Design Drought has prompted the SFPUC to create an Alternative Water Supply Plan that would double the SFPUC budget (and water rates) to produce expensive water we won’t ever need, while continuing to minimize river flows in the Tuolumne.

Low flows along the Tuolumne River harm the environment: the wild salmon population is on the brink of collapse and the scarcity of this keystone species negatively impacts riparian, delta, bay, and ocean ecosystems as well; frontline communities experience illness from toxic algae blooms and water scarcity; and Indigenous Tribes and commercial fishing communities that rely on healthy fisheries experience the collapse of lifeways and economies.

We encourage you to send a letter to the San Francisco Board of Supervisors, demanding science-backed water policies and a financially viable SFPUC budget.

Let your supervisor know that the citizens call for an independent audit of the SFPUC!

', - representatives: JSON.stringify([ - { - name: 'Connie Chan', - title: 'District 1 Supervisor', - photoUrl: - 'https://sfbos.org/sites/default/files/Connie_Chan_2023.jpg', - address_line1: '1 Dr Carlton B Goodlett Pl', - address_line2: '#244', - address_city: 'San Francisco', - address_state: 'CA', - address_zip: '94102', - address_country: 'US', - email: 'chanstaff@sfgov.org' - }, - { - name: 'Catherine Stefani', - title: 'District 2 Supervisor', - photoUrl: - 'https://sfbos.org/sites/default/files/Supervisor_Stefani_2018.jpg', - address_line1: '1 Dr Carlton B Goodlett Pl', - address_line2: '#244', - address_city: 'San Francisco', - address_state: 'CA', - address_zip: '94102', - address_country: 'US', - email: 'Catherine.Stefani@sfgov.org' - }, - { - name: 'Aaron Peskin', - title: 'District 3 Supervisor', - photoUrl: - 'https://sfbos.org/sites/default/files/Aaron_Peskin_2023.jpg', - address_line1: '1 Dr Carlton B Goodlett Pl', - address_line2: '#244', - address_city: 'San Francisco', - address_state: 'CA', - address_zip: '94102', - address_country: 'US', - email: 'Aaron.Peskin@sfgov.org' - }, - { - name: 'Joel Engardio', - title: 'District 4 Supervisor', - photoUrl: - 'https://sfbos.org/sites/default/files/Joel_Engardio_2023.jpg', - address_line1: '1 Dr Carlton B Goodlett Pl', - address_line2: '#244', - address_city: 'San Francisco', - address_state: 'CA', - address_zip: '94102', - address_country: 'US', - email: '' - }, - { - name: 'Dean Preston', - title: 'District 5 Supervisor', - photoUrl: - 'https://sfbos.org/sites/default/files/Dean_Preston_2023.jpg', - address_line1: '1 Dr Carlton B Goodlett Pl', - address_line2: '#244', - address_city: 'San Francisco', - address_state: 'CA', - address_zip: '94102', - address_country: 'US', - email: 'prestonstaff@sfgov.org' - }, - { - name: 'Matt Dorsey', - title: 'District 6 Supervisor', - photoUrl: - 'https://sfbos.org/sites/default/files/Dorsey_2022_lg.jpg', - address_line1: '1 Dr Carlton B Goodlett Pl', - address_line2: '#244', - address_city: 'San Francisco', - address_state: 'CA', - address_zip: '94102', - address_country: 'US', - email: 'DorseyStaff@sfgov.org' - }, - { - name: 'Myrna Melgar', - title: 'District 7 Supervisor', - photoUrl: - 'https://sfbos.org/sites/default/files/Myrna_Melgar_2023.jpg', - address_line1: '1 Dr Carlton B Goodlett Pl', - address_line2: '#244', - address_city: 'San Francisco', - address_state: 'CA', - address_zip: '94102', - address_country: 'US', - email: 'melgarstaff@sfgov.org' - }, - { - name: 'Rafael Mandelman', - title: 'District 8 Supervisor', - photoUrl: - 'https://sfbos.org/sites/default/files/Supervisor_Mandelman_2018.jpg', - address_line1: '1 Dr Carlton B Goodlett Pl', - address_line2: '#244', - address_city: 'San Francisco', - address_state: 'CA', - address_zip: '94102', - address_country: 'US', - email: 'mandelmanstaff@sfgov.org' - }, - { - name: 'Hillary Ronen', - title: 'District 9 Supervisor', - photoUrl: - 'https://sfbos.org/sites/default/files/Supervisor_Ronen_2019.jpg', - address_line1: '1 Dr Carlton B Goodlett Pl', - address_line2: '#244', - address_city: 'San Francisco', - address_state: 'CA', - address_zip: '94102', - address_country: 'US', - email: 'RonenStaff@sfgov.org' - }, - { - name: 'Shamann Walton', - title: 'District 10 Supervisor', - photoUrl: - 'https://sfbos.org/sites/default/files/Shamann_Walton_2023.jpg', - address_line1: '1 Dr Carlton B Goodlett Pl', - address_line2: '#244', - address_city: 'San Francisco', - address_state: 'CA', - address_zip: '94102', - address_country: 'US', - email: 'waltonstaff@sfgov.org' - }, - { - name: 'Ahsha Safai', - title: 'District 11 Supervisor', - photoUrl: - 'https://sfbos.org/sites/default/files/Ahsha_Safai_2023.jpg', - address_line1: '1 Dr Carlton B Goodlett Pl', - address_line2: '#244', - address_city: 'San Francisco', - address_state: 'CA', - address_zip: '94102', - address_country: 'US', - email: 'Ahsha.Safai@sfgov.org' - } - ]), - assets: JSON.stringify({ - campaign_logo: - 'https://images.squarespace-cdn.com/content/v1/5eebc0039b04b54b2fb0ce52/1598500758914-E5HAIIGCP0ZXKKMN2FT0/TRT+Logo-13.png?format=500w', - campaign_background: - 'https://images.squarespace-cdn.com/content/v1/5eebc0039b04b54b2fb0ce52/1610135975708-FV42Q30BPWF887M05O51/Poppies-13.jpg?format=1500w', - 'campaign-img-1': - 'https://images.squarespace-cdn.com/content/v1/5eebc0039b04b54b2fb0ce52/1609785926325-63M9MY247ORIL8ON8P5E/tuolumne-camp-960x540.jpg?format=1500w', - 'campaign-img-2': - 'https://images.squarespace-cdn.com/content/v1/5eebc0039b04b54b2fb0ce52/1592586646372-TBY3WC065NJ04KT2B38Z/000091400001.jpg?format=1500w', - 'campaign-img-3': - 'https://images.squarespace-cdn.com/content/v1/5eebc0039b04b54b2fb0ce52/1609781359705-Q5YNFL6DET5ORHW62ZU7/IMG_2249_WEBSITE+copy.jpg?format=1500w' - }) - }, - { - id: 3, - organization: 'Save California Salmon', - name: 'Save California Salmon', - cause: 'Civic Rights', - type: 'Grant', - page_url: 'https://www.californiasalmon.org/', - letter_template_id: 1, + page_url: 'https://rutgersaaup.org/wp-content/uploads/2024/08/Rutgers-Caste-Report-August-2024.pdf', + letter_template_id: 2, campaign_tagline: - 'Restoring and Protecting California Salmon and Rivers for Future Generations', - campaign_text: - '

#UNDAMTHEKLAMATH

Save California Salmon (SCS) is dedicated to policy change and community advocacy for Northern California’s salmon and fish dependent people. We support the fisheries and water protection work of the local communities, and advocate effective policy change for clean water, restored fisheries and vibrant communities. We aim to help to support Tribes and the general public in engaging with public comments related to water pollution, fisheries, and beneficial use issues.

Restoration of the Klamath River does not stop with dam removal. Salmon populations are continuing to plummet throughout California, leaving Tribal communities without salmon for subsistence, and ocean fishermen without a season. Restoration of the Klamath’s tributaries, which are often dewatered for animal agriculture, is also critical. We continued to support Tribal efforts to establish both permanent and temporary emergency flows in the Scott and Shasta Rivers through the California Water Resources Control Board. In December, the board passed emergency irrigation curtailments for both rivers, and we are still pushing for permanent instream flow requirements.

We also continued to fight for Trinity River flows, which are critical to the river, and to stop fish kills in the Klamath River. The Trinity is the Klamath’s largest tributary, but it is also an artificial Sacramento River tributary that feeds the Central Valley Water Project. The federal government is working on a new Biological Opinion for Endangered Species (water operations plan) for the Central Valley and State Water Projects. We are calling for a separate, protective Biological Opinion for the Trinity River, and for flows in the Bay Delta watersheds.

We are deeply dedicated to dam removal and flow restoration in all the North State’s watersheds. We want salmon back for all Northern California Tribes, which is why we are hopeful about Pacific Gas & Electric’s (PGE) December proposal to fully decommission the Eel River Dams.

', + 'URGE RUTGERS TO PRIORITIZE CASTE EQUITY', + campaign_text: '

We applaud Rutgers University for taking a crucial step toward addressing caste inequity through the recent University Task Force Report on Caste Discrimination in Higher Education and at Rutgers Global caste systems enforce discrimination through inherited social status. They are a systemic injustice that has long been overlooked in the United States, despite its prevalence in many American institutions including higher education. That is why the findings of this report are so crucial. By recommending to add caste as a protected category, Rutgers has an opportunity to lead the way in creating equitable spaces for all, especially for caste-oppressed faculty, students, and workers who experience this bias.

The testimonies presented in Rutgers’ task force report are a powerful reminder of the urgent need to address caste-based exclusion, harassment, and inequities in higher education. Caste is not an abstract concept; it is a harsh reality for millions. Caste discrimination spans across industries and includes bullying, harassment, bias, wage theft, sexual harassment, and even trafficking. Caste-oppressed individuals have also been denied rental housing upon the discovery of their caste identity. This issue has gained significant attention in New Jersey following human trafficking allegations against the BAPS temples, where caste-oppressed workers were held against their will and paid just a dollar an hour under inhumane conditions

In New Jersey there are many communities who suffer caste discrimination in their communities from Africa, South Asia, Asia, and Indigenous residents of the state. Students, faculty and staff from these backgrounds must be able to access the campus as a place of learning and as a workplace free from discrimination and harm.

From workplace discrimination to campus bullying, the insidious impacts of caste privilege have been well-documented by marginalized communities, In our own 2016 report Caste in the United States we have found caste oppressed people face alarming discrimination and harassment with 1 in 4 facing physical and verbal assault, 1 in 3 education discrimination and 2 out 3 workplace discrimination.

As a U.S.-based civil rights group we urge Rutgers’ administration **to fully adopt the task force’s recommendations and implement robust enforcement mechanisms.** This includes education on caste equity for students, staff, and faculty and meaningful support for those who come forward with experiences of caste-based harm.

As Rutgers advances this work, we caution against narratives that dismiss caste protections as “anti-Hindu” or as targeting specific communities. Such arguments weaponize bad faith arguments and privilege to silence Dalit voices and maintain systems of oppression. Caste is found across multiple geographies and faiths and it must be addressed as its own system of exclusion. We believe in fostering dialogue that centers the experiences of the most vulnerable while rejecting extremist  rhetoric that masquerades falsely as a defense of cultural identity.

Rutgers’ initiative is part of a broader, necessary movement to confront caste oppression in the United States. We look forward to standing alongside other universities and institutions in their journey toward caste equity. Together, we can build communities where everyone can thrive with dignity and equal opportunity.

In solidarity,

Equality Labs

', supplemental_text: - '

At the end of 2020 California, Oregon and Berkshire Hathaway entered a new agreement to undam the Klamath River. This decision came after almost twenty years of organizing, testifying, actions and planning from the native peoples of the Klamath basin, coastal fishermen and their allies. This year we continue our advocacy to make sure these dams come down.

', + '

Caste-oppressed students and staff deserve protection—yet Rutgers University continues to delay adopting crucial caste protections in its anti-discrimination policy. This hesitation comes after pressure from far-right nationalist groups that aim to erase the realities of caste-based harm.

In August 2024, the Rutgers Task Force on Caste Discrimination recommended adding caste as a protected category after collecting powerful testimony from affected community members. These recommendations are a critical step toward equity but remain stalled.

It’s time to demand action! Let’s ensure Rutgers doesn’t back down in the face of opposition. Flood the administration’s inboxes today and call for the immediate adoption of caste protections. Together, we can build a campus where no one has to endure caste discrimination.

', representatives: JSON.stringify([ { - name: 'Connie Chan', - title: 'District 1 Supervisor', - photoUrl: - 'https://sfbos.org/sites/default/files/Connie_Chan_2023.jpg', - address_line1: '1 Dr Carlton B Goodlett Pl', - address_line2: '#244', - address_city: 'San Francisco', - address_state: 'CA', - address_zip: '94102', + name: 'President Jonathan Holloway', + title: 'President, Rutgers University', + photoUrl: 'https://www.rutgers.edu/sites/default/files/styles/3x4_one_third_full_1024_1x/public/2020-07/pro_NR20HollowayJonathan1819.jpg?h=ef631461&itok=uRWXEI4G', + address_line1: '7 College Avenue', + address_line2: '2nd Floor', + address_city: 'New Brunswick', + address_state: 'NJ', + address_zip: '08901', address_country: 'US', - email: 'chanstaff@sfgov.org' + email: 'president@rutgers.edu' }, { - name: 'Catherine Stefani', - title: 'District 2 Supervisor', - photoUrl: - 'https://sfbos.org/sites/default/files/Supervisor_Stefani_2018.jpg', - address_line1: '1 Dr Carlton B Goodlett Pl', - address_line2: '#244', - address_city: 'San Francisco', - address_state: 'CA', - address_zip: '94102', - address_country: 'US', - email: 'Catherine.Stefani@sfgov.org' - }, - { - name: 'Aaron Peskin', - title: 'District 3 Supervisor', - photoUrl: - 'https://sfbos.org/sites/default/files/Aaron_Peskin_2023.jpg', - address_line1: '1 Dr Carlton B Goodlett Pl', - address_line2: '#244', - address_city: 'San Francisco', - address_state: 'CA', - address_zip: '94102', - address_country: 'US', - email: 'Aaron.Peskin@sfgov.org' - }, - { - name: 'Joel Engardio', - title: 'District 4 Supervisor', - photoUrl: - 'https://sfbos.org/sites/default/files/Joel_Engardio_2023.jpg', - address_line1: '1 Dr Carlton B Goodlett Pl', - address_line2: '#244', - address_city: 'San Francisco', - address_state: 'CA', - address_zip: '94102', + name: 'Anna (Enobong) Branch', + title: 'Senior Vice President for University Equity and Inclusion', + photoUrl: 'https://www.rutgers.edu/sites/default/files/styles/3x4_one_third_full_1024_1x/public/2020-09/pro_Ann_Branch.jpg?h=3dfac914&itok=rA6GxwC_', + address_line1: '106 Sommerset Street', + address_line2: '7th Floor', + address_city: 'New Brunswick', + address_state: 'NJ', + address_zip: '08901', address_country: 'US', - email: '' + email: 'enobong.branch@rutgers.edu' }, { - name: 'Dean Preston', - title: 'District 5 Supervisor', - photoUrl: - 'https://sfbos.org/sites/default/files/Dean_Preston_2023.jpg', - address_line1: '1 Dr Carlton B Goodlett Pl', - address_line2: '#244', - address_city: 'San Francisco', - address_state: 'CA', - address_zip: '94102', - address_country: 'US', - email: 'prestonstaff@sfgov.org' - }, - { - name: 'Matt Dorsey', - title: 'District 6 Supervisor', - photoUrl: - 'https://sfbos.org/sites/default/files/Dorsey_2022_lg.jpg', - address_line1: '1 Dr Carlton B Goodlett Pl', - address_line2: '#244', - address_city: 'San Francisco', - address_state: 'CA', - address_zip: '94102', - address_country: 'US', - email: 'DorseyStaff@sfgov.org' - }, - { - name: 'Myrna Melgar', - title: 'District 7 Supervisor', - photoUrl: - 'https://sfbos.org/sites/default/files/Myrna_Melgar_2023.jpg', - address_line1: '1 Dr Carlton B Goodlett Pl', - address_line2: '#244', - address_city: 'San Francisco', - address_state: 'CA', - address_zip: '94102', - address_country: 'US', - email: 'melgarstaff@sfgov.org' - }, - { - name: 'Rafael Mandelman', - title: 'District 8 Supervisor', - photoUrl: - 'https://sfbos.org/sites/default/files/Supervisor_Mandelman_2018.jpg', - address_line1: '1 Dr Carlton B Goodlett Pl', - address_line2: '#244', - address_city: 'San Francisco', - address_state: 'CA', - address_zip: '94102', - address_country: 'US', - email: 'mandelmanstaff@sfgov.org' - }, - { - name: 'Hillary Ronen', - title: 'District 9 Supervisor', - photoUrl: - 'https://sfbos.org/sites/default/files/Supervisor_Ronen_2019.jpg', - address_line1: '1 Dr Carlton B Goodlett Pl', - address_line2: '#244', - address_city: 'San Francisco', - address_state: 'CA', - address_zip: '94102', - address_country: 'US', - email: 'RonenStaff@sfgov.org' - }, - { - name: 'Shamann Walton', - title: 'District 10 Supervisor', - photoUrl: - 'https://sfbos.org/sites/default/files/Shamann_Walton_2023.jpg', - address_line1: '1 Dr Carlton B Goodlett Pl', - address_line2: '#244', - address_city: 'San Francisco', - address_state: 'CA', - address_zip: '94102', - address_country: 'US', - email: 'waltonstaff@sfgov.org' - }, - { - name: 'Ahsha Safai', - title: 'District 11 Supervisor', - photoUrl: - 'https://sfbos.org/sites/default/files/Ahsha_Safai_2023.jpg', - address_line1: '1 Dr Carlton B Goodlett Pl', - address_line2: '#244', - address_city: 'San Francisco', - address_state: 'CA', - address_zip: '94102', + name: 'Prabhas Moghe', + title: 'Executive Vice President for Academic Affairs at Rutgers', + photoUrl: 'https://www.rutgers.edu/sites/default/files/styles/max_width_embed_default_2x/public/2020-09/pro_Prabhas_Moghe.jpg?itok=dLd3TLhW', + address_line1: '7 College Avenue', + address_line2: '2nd Floor', + address_city: 'New Brunswick', + address_state: 'NJ', + address_zip: '08901', address_country: 'US', - email: 'Ahsha.Safai@sfgov.org' + email: 'nbprovost@rutgers.edu.' } ]), assets: JSON.stringify({ - campaign_logo: - 'https://static.wixstatic.com/media/d97ff6_b61eff2e17cc4511b92752e6af420835~mv2.png/v1/fill/w_96,h_97,al_c,q_85,usm_0.66_1.00_0.01,enc_auto/White%20circle%2C%20Black%20background%20SCS%20Logo.png', - campaign_background: 'https://i.imgur.com/4OsValj.png', - 'campaign-img-1': 'https://i.imgur.com/fGMy8Wz.png', - 'campaign-img-2': 'https://i.imgur.com/toMnnE0.png', - 'campaign-img-3': 'https://i.imgur.com/wXRXDCd.png' + campaign_logo: 'https://ggjalliance.org/wp-content/uploads/2019/09/Equality-Labs.png', + campaign_background: 'https://media.assettype.com/freepressjournal/2024-09-04/i722yxsy/lg_NR15OldQueensGate0889_edit.jpg?rect=0%2C0%2C3900%2C2194&w=1200&auto=format%2Ccompress&ogImage=true', + 'campaign-img-1': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ-yngrxizvU5kAZ3CP9-iQnn1OD14eXkpeXUYo96KOL6sg19Icwoes_JYlm_a61pzAcRE&usqp=CAU', + 'campaign-img-2': 'https://images-prod.gothamist.com/images/GettyImages-1481222828.width-1000.jpg', + 'campaign-img-3': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS2X0OYEKhzrxmyMymuEaqDUIq0jDakYX4i4jaqRI3AUs0svGfcNDbpdatY4WUD6LMPRqg&usqp=CAU' }) } ]) diff --git a/src/components/LetterLoad.vue b/src/components/LetterLoad.vue index e0501b66f..a5cbfe522 100644 --- a/src/components/LetterLoad.vue +++ b/src/components/LetterLoad.vue @@ -24,21 +24,10 @@ {{ selectedRep.address_zip }}

-
{{ user.name }}
-
- {{ user.line1 }} -
- {{ user.line2 }} -
-
- {{ formattedCityState }} -
- -

{{ user.name }}

clicked @@ -135,10 +124,13 @@ export default { this.userSelections.representativeName = this.selectedRep.name this.letterBody = this.letterTemplate.html + + // First Letter Render to set user's name + this.renderLetter() }, methods: { renderLetter() { - axios.post('/api/v1/letter_templates/render', { mergeVariables: { ...this.userSelections, representativeName: this.selectedRep.name }, templateId: this.letterTemplate.id }) + axios.post('/api/v1/letter_templates/render', { mergeVariables: { ...this.userSelections, representativeName: this.selectedRep.name, name: this.user.name }, templateId: this.letterTemplate.id }) .then((res) => { this.letterBody = res.data.letter }) diff --git a/src/store/index.js b/src/store/index.js index e5b55690a..cd0e31356 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -26,7 +26,7 @@ export default new Vuex.Store({ lobReturnAddressId: '', selectedRep: {}, userData: { - name: '', + name: '', line1: '', line2: '', city: '', From 80e7d7ad8b2eed24ec74606fe01afcc4fbd11dad Mon Sep 17 00:00:00 2001 From: Glenn Date: Wed, 18 Dec 2024 08:38:37 -0600 Subject: [PATCH 17/21] Fixed name issue --- server/db/seeds/development/01-seed-letter_templates-table.js | 2 +- src/components/LetterLoad.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/db/seeds/development/01-seed-letter_templates-table.js b/server/db/seeds/development/01-seed-letter_templates-table.js index 03c84e59e..757c04bec 100644 --- a/server/db/seeds/development/01-seed-letter_templates-table.js +++ b/server/db/seeds/development/01-seed-letter_templates-table.js @@ -38,7 +38,7 @@ module.exports = { name: 'rutgers caste equity petition', subject: 'To the Administration of Rutgers University', merge_variables: {}, - html: '

Dear Rutgers Administration,

I write today to urge Rutgers University to take bold action by adopting all four recommendations from the University Task Force on Caste Discrimination, including adding caste as a protected category within the institution’s anti-discrimination policies. This essential step would reaffirm Rutgers’ commitment to fostering an inclusive and equitable campus for all students, faculty, and staff.

Caste discrimination is a grave and pervasive form of oppression that transcends borders and affects marginalized communities globally. At Rutgers, caste-oppressed students and staff deserve the same protections afforded to others against bias and harm. Recognizing caste explicitly in Rutgers’ policies will ensure that those impacted have the institutional support needed to seek accountability and justice.

The inclusion of caste protections is not about targeting any particular group; it is about creating an environment where equity is non-negotiable. Opponents of this policy often use misinformation to sideline the voices of caste-oppressed communities. Rutgers must not allow such narratives to delay progress. Instead, it should set a powerful example by prioritizing the voices of those most impacted and centering their lived experiences in its decision-making.

As a university that prides itself on diversity, equity, and inclusion, Rutgers has an opportunity to demonstrate what those values look like in practice. By taking immediate steps to implement the Task Force’s recommendations, Rutgers can establish itself as a leader in addressing caste oppression in higher education.

This is a pivotal moment for Rutgers to be on the right side of history. I urge you to act now and adopt caste protections, ensuring that all members of your community can thrive with dignity, safety, and equality.

In solidarity,

{{ name }}

' + html: '

Dear Rutgers Administration,

I write today to urge Rutgers University to take bold action by adopting all four recommendations from the University Task Force on Caste Discrimination, including adding caste as a protected category within the institution’s anti-discrimination policies. This essential step would reaffirm Rutgers’ commitment to fostering an inclusive and equitable campus for all students, faculty, and staff.

Caste discrimination is a grave and pervasive form of oppression that transcends borders and affects marginalized communities globally. At Rutgers, caste-oppressed students and staff deserve the same protections afforded to others against bias and harm. Recognizing caste explicitly in Rutgers’ policies will ensure that those impacted have the institutional support needed to seek accountability and justice.

The inclusion of caste protections is not about targeting any particular group; it is about creating an environment where equity is non-negotiable. Opponents of this policy often use misinformation to sideline the voices of caste-oppressed communities. Rutgers must not allow such narratives to delay progress. Instead, it should set a powerful example by prioritizing the voices of those most impacted and centering their lived experiences in its decision-making.

As a university that prides itself on diversity, equity, and inclusion, Rutgers has an opportunity to demonstrate what those values look like in practice. By taking immediate steps to implement the Task Force’s recommendations, Rutgers can establish itself as a leader in addressing caste oppression in higher education.

This is a pivotal moment for Rutgers to be on the right side of history. I urge you to act now and adopt caste protections, ensuring that all members of your community can thrive with dignity, safety, and equality.

In solidarity,

{{ firstName }} {{ lastName }}

' } ]) } diff --git a/src/components/LetterLoad.vue b/src/components/LetterLoad.vue index a5cbfe522..fcc4c6733 100644 --- a/src/components/LetterLoad.vue +++ b/src/components/LetterLoad.vue @@ -130,7 +130,7 @@ export default { }, methods: { renderLetter() { - axios.post('/api/v1/letter_templates/render', { mergeVariables: { ...this.userSelections, representativeName: this.selectedRep.name, name: this.user.name }, templateId: this.letterTemplate.id }) + axios.post('/api/v1/letter_templates/render', { mergeVariables: { ...this.userSelections, representativeName: this.selectedRep.name, firstName: '', lastName: '' }, templateId: this.letterTemplate.id }) .then((res) => { this.letterBody = res.data.letter }) From 3b613c26977ebe71491ed402a356fbc4e7198f38 Mon Sep 17 00:00:00 2001 From: Glenn Date: Fri, 20 Dec 2024 08:34:09 -0600 Subject: [PATCH 18/21] Made images on landing page optional --- .../db/seeds/development/02-seed-campaigns-table.js | 2 +- src/components/CampaignBlurb.vue | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/server/db/seeds/development/02-seed-campaigns-table.js b/server/db/seeds/development/02-seed-campaigns-table.js index 7f021355a..9e4ee9898 100644 --- a/server/db/seeds/development/02-seed-campaigns-table.js +++ b/server/db/seeds/development/02-seed-campaigns-table.js @@ -142,7 +142,7 @@ module.exports = { } ]), assets: JSON.stringify({ - campaign_logo: 'https://ggjalliance.org/wp-content/uploads/2019/09/Equality-Labs.png', + campaign_logo: 'https://i.imgur.com/0I80XGh.png', campaign_background: 'https://media.assettype.com/freepressjournal/2024-09-04/i722yxsy/lg_NR15OldQueensGate0889_edit.jpg?rect=0%2C0%2C3900%2C2194&w=1200&auto=format%2Ccompress&ogImage=true', 'campaign-img-1': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ-yngrxizvU5kAZ3CP9-iQnn1OD14eXkpeXUYo96KOL6sg19Icwoes_JYlm_a61pzAcRE&usqp=CAU', 'campaign-img-2': 'https://images-prod.gothamist.com/images/GettyImages-1481222828.width-1000.jpg', diff --git a/src/components/CampaignBlurb.vue b/src/components/CampaignBlurb.vue index 71acad4b7..9e643c400 100644 --- a/src/components/CampaignBlurb.vue +++ b/src/components/CampaignBlurb.vue @@ -2,22 +2,25 @@
supplemental image one supplemental image two supplemental image three
-
+

Date: Sat, 8 Mar 2025 19:00:16 -0600 Subject: [PATCH 19/21] Added seed data for pueblo action alliance No more landing page! --- .env | 2 +- script/stringify.js | 339 ++---------------- .../01-seed-letter_templates-table.js | 20 ++ .../development/02-seed-campaigns-table.js | 37 ++ src/components/SearchReps.vue | 20 +- src/router/index.js | 23 +- 6 files changed, 117 insertions(+), 324 deletions(-) diff --git a/.env b/.env index d1873d52e..f3b43d191 100644 --- a/.env +++ b/.env @@ -32,7 +32,7 @@ TWILIO_AUTH_TOKEN=TWILIO_SECRET_KEY # **We always run in single-campaign mode now so this is mandatory!** # Use campaign seeder file for local dev campaigns. VUE_APP_CAMPAIGN_MODE=single -VUE_APP_FEATURED_CAMPAIGN=2 +VUE_APP_FEATURED_CAMPAIGN=3 VUE_APP_EMPTY_TRANSACTIONS=off VUE_APP_SHOW_EXT_DONATION=false diff --git a/script/stringify.js b/script/stringify.js index 6a5046bd1..7cdff1315 100644 --- a/script/stringify.js +++ b/script/stringify.js @@ -1,329 +1,30 @@ +/* const reps = JSON.stringify([ { - name: 'Dr. Buu Nygren', - title: 'President of the Navajo Nation', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/photo_P_Nygren.jpg?resize=1080%2C1080&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: 'alray.nelson@navajo-nsn.gov' - }, - { - name: 'Jasmine Blackwater-Nygren', - title: 'First Lady of the Navajo Nation', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/photo_FL_Nygren-Blackwater.jpg?resize=1080%2C1080&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: 'alray.nelson@navajo-nsn.gov' - }, - { - name: 'Richelle Montoya', - title: 'Vice President of the Navajo Nation', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/photo_VP_Montoya.jpg?resize=1080%2C1080&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: 'josie.bowman@navajo-nsn.gov' - }, - { - name: 'Ethel Branch', - title: 'Department of Justice, Attorney General', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/attorney_general_Branch.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Sean McCabe', - title: 'Office of the Controller, Controller', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/controller_McCabe.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Justin Ahasteen', - title: 'Navajo Nation Washington Office, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/director_Ahasteen.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Heather Clah', - title: 'Department of Justice, Deputy Attorney General', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2024/04/dag_Clah.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', + name: 'Stephen Hoffman', + title: 'LANL SWEIS Document Manager, DOE/NNSA ', + photoUrl: 'https://imgs.search.brave.com/G46oqr3VnummnoFmkqT_NqalvvWvKQxpoX-EJITKqGQ/rs:fit:860:0:0:0/g:ce/aHR0cHM6Ly9uYXRp/b25hbG1hZ2xhYi5v/cmcvaW1hZ2VzL2xh/eW91dC9sb3MtYWxh/bW9zLWxvZ28uanBn/P2Q9MjAyMzAyMDc', + address_line1: '3747 West Jemez Road ', address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', + address_city: 'Los Alamos', + address_state: 'NM', + address_zip: '87544', address_country: 'US', - email: '' - }, - { - name: 'Thomas Cody', - title: 'Division of Social Services, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/director_Cody.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Sherylene Yazzie', - title: 'Department of Health, Acting Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/Seal_gray_gradient.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Roy Tracy', - title: 'Department of Diné Education, Interim Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2024/04/director_Tracy.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Tony Skrelunas', - title: 'Division of Economic Development, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/director_Skrelunas.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Bobbie Ann Baldwin', - title: 'Navajo Nation Veterans Administration, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2024/04/director_Baldwin.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Shawnevan Dale', - title: 'Executive Director, Division of General Services', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/director_Dale.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Tom Platero', - title: 'Division of Transportation, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/director_Platero.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Effie Edsitty', - title: 'Office of the Navajo Tax Commission, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/director_Edsitty.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Arbin Mitchell', - title: 'Division of Community Development, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/director_Mitchell.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Sarah Slim', - title: 'Navajo-Hopi Land Commission Office, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2024/04/director_Slim_2.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'W. Mike Halona', - title: 'Division of Natural Resources, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/director_Halona.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Byron C. Shorty', - title: - 'Telecommunications Regulatory Commission Office, Acting Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2024/09/director_Shorty.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Michael Anderson', - title: 'Division of Public Safety, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/director_Anderson-1.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Stephen Etsitty', - title: 'Navajo Nation Environmental Protection Agency, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/director_Etsitty.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Dominic Beyal', - title: 'Office of Management & Budget, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2024/04/director_Beyal.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Lisa Jymm', - title: 'Navajo Nation Fiscal Recovery Fund Office, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2024/03/director.Jymm_.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' - }, - { - name: 'Reycita Toddy', - title: 'Division of Human Resources, Executive Director', - photoUrl: - 'https://i0.wp.com/opvp.navajo-nsn.gov/wp-content/uploads/2023/12/Seal_gray_gradient.jpg?resize=1080%2C1440&ssl=1', - address_line1: 'PO Box 7440', - address_line2: '', - address_city: 'Window Rock', - address_state: 'AZ', - address_zip: '86515', - address_country: 'US', - email: '' + email: 'lanlsweis@nnsa.doe.gov' } ]) + */ + -/* const assets = JSON.stringify({ - campaign_logo: 'https://i.imgur.com/o3lxGJD.png', - campaign_background: 'https://i.imgur.com/qGOHdiP.jpeg', - 'campaign-img-1': 'https://i.imgur.com/h88GBNC.jpeg', - 'campaign-img-2': 'https://i.imgur.com/lcQWK6p.jpeg', - 'campaign-img-3': 'https://i.imgur.com/bnPQVOR.jpeg', - 'infographic': 'https://i.imgur.com/BJCPDCR.jpeg' + campaign_logo: 'https://i.imgur.com/0I80XGh.png', + campaign_background: 'https://media.assettype.com/freepressjournal/2024-09-04/i722yxsy/lg_NR15OldQueensGate0889_edit.jpg?rect=0%2C0%2C3900%2C2194&w=1200&auto=format%2Ccompress&ogImage=true', + infographic: 'https://i.imgur.com/I7E3J5Q.png', + 'campaign-img-1': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ-yngrxizvU5kAZ3CP9-iQnn1OD14eXkpeXUYo96KOL6sg19Icwoes_JYlm_a61pzAcRE&usqp=CAU', + 'campaign-img-2': 'https://images-prod.gothamist.com/images/GettyImages-1481222828.width-1000.jpg', + 'campaign-img-3': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS2X0OYEKhzrxmyMymuEaqDUIq0jDakYX4i4jaqRI3AUs0svGfcNDbpdatY4WUD6LMPRqg&usqp=CAU' }) - */ -console.log(reps) -//console.log(assets) + +//console.log(reps) +console.log(assets) diff --git a/server/db/seeds/development/01-seed-letter_templates-table.js b/server/db/seeds/development/01-seed-letter_templates-table.js index 757c04bec..1fc2c066c 100644 --- a/server/db/seeds/development/01-seed-letter_templates-table.js +++ b/server/db/seeds/development/01-seed-letter_templates-table.js @@ -39,6 +39,26 @@ module.exports = { subject: 'To the Administration of Rutgers University', merge_variables: {}, html: '

Dear Rutgers Administration,

I write today to urge Rutgers University to take bold action by adopting all four recommendations from the University Task Force on Caste Discrimination, including adding caste as a protected category within the institution’s anti-discrimination policies. This essential step would reaffirm Rutgers’ commitment to fostering an inclusive and equitable campus for all students, faculty, and staff.

Caste discrimination is a grave and pervasive form of oppression that transcends borders and affects marginalized communities globally. At Rutgers, caste-oppressed students and staff deserve the same protections afforded to others against bias and harm. Recognizing caste explicitly in Rutgers’ policies will ensure that those impacted have the institutional support needed to seek accountability and justice.

The inclusion of caste protections is not about targeting any particular group; it is about creating an environment where equity is non-negotiable. Opponents of this policy often use misinformation to sideline the voices of caste-oppressed communities. Rutgers must not allow such narratives to delay progress. Instead, it should set a powerful example by prioritizing the voices of those most impacted and centering their lived experiences in its decision-making.

As a university that prides itself on diversity, equity, and inclusion, Rutgers has an opportunity to demonstrate what those values look like in practice. By taking immediate steps to implement the Task Force’s recommendations, Rutgers can establish itself as a leader in addressing caste oppression in higher education.

This is a pivotal moment for Rutgers to be on the right side of history. I urge you to act now and adopt caste protections, ensuring that all members of your community can thrive with dignity, safety, and equality.

In solidarity,

{{ firstName }} {{ lastName }}

' + }, + { + id: 3, + name: 'Pueblo Action Alliance Los Alamos Campaign', + subject: 'Halt Los Alamos National Lab’s Flanged Tritium Waste Container (FTWC) Venting in Pueblo Communities', + merge_variables: {}, + html: '

Dear Mr. Hoffman,

\ +

 

\ +

I\'m submitting a public comment to express my concern regarding the NNSA/LANL\'s draft Site-Wide Environmental Impact Statement. (EPCU) project outline still poses adverse threats to the Caja del Rio\'s sensitive ecosystem, cultural resources utilized by surrounding Pueblos, and land-based learning opportunities for Pueblo youth and other community members.

\ +

• The NNSA and DOE need to engage in Free, Prior and Informed Consent practices that ensure meaningful consultation with tribal leadership.

\ +

Increasing plutonium pit production to grow the nuclear weapons arsenal is in direct contradiction to the wishes of concerned Pueblo community members to stop plutonium pit production altogether.

\ +

• There must be comprehensive cleanup efforts of existing radioactive nuclear waste which continues to threaten groundwater sources and soil health.

\ +

• LANL\'s permit to vent tritium as another means to expand and continue operations has already faced heavy opposition due to the radioactive exposure to the surrounding landscapes and community. This is also in violation of the Clean Water Act.

\ +

Modifying and expanding LAN\'s facilities would put an additional strain on the region\'s water supply issues. Our water must be protected and preserved sustainably for our future generations.

\ +

Addressing the concerns outlined in this email/letter will allow impacted Pueblo communities to voice opposition on the Los Alamos National Lab\'s expanded nuclear weapons programs and the violent legacy of environmental degradation to the land, air, and water.

\ +

Sincerely,

\ +

 

\ +

{{ firstName }} {{ lastName }}

\ +

 

\ +

 

' } ]) } diff --git a/server/db/seeds/development/02-seed-campaigns-table.js b/server/db/seeds/development/02-seed-campaigns-table.js index 9e4ee9898..21b29d340 100644 --- a/server/db/seeds/development/02-seed-campaigns-table.js +++ b/server/db/seeds/development/02-seed-campaigns-table.js @@ -144,6 +144,43 @@ module.exports = { assets: JSON.stringify({ campaign_logo: 'https://i.imgur.com/0I80XGh.png', campaign_background: 'https://media.assettype.com/freepressjournal/2024-09-04/i722yxsy/lg_NR15OldQueensGate0889_edit.jpg?rect=0%2C0%2C3900%2C2194&w=1200&auto=format%2Ccompress&ogImage=true', + infographic: 'https://i.imgur.com/I7E3J5Q.png', + 'campaign-img-1': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ-yngrxizvU5kAZ3CP9-iQnn1OD14eXkpeXUYo96KOL6sg19Icwoes_JYlm_a61pzAcRE&usqp=CAU', + 'campaign-img-2': 'https://images-prod.gothamist.com/images/GettyImages-1481222828.width-1000.jpg', + 'campaign-img-3': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS2X0OYEKhzrxmyMymuEaqDUIq0jDakYX4i4jaqRI3AUs0svGfcNDbpdatY4WUD6LMPRqg&usqp=CAU' + }) + }, + { + id: 3, + organization: 'Pueblo Action Alliance', + name: 'Pueblo Action Alliance', + cause: 'Civic Rights', + type: 'Grant', + page_url: 'https://rutgersaaup.org/wp-content/uploads/2024/08/Rutgers-Caste-Report-August-2024.pdf', + letter_template_id: 3, + campaign_tagline: + 'Halt Los Alamos National Lab’s Flanged Tritium Waste Container (FTWC) Venting in Pueblo Communities', + campaign_text: '

Los Alamos National Labs (LANL) has proposed the Flanged Tritium Waste Container venting, four containers, near LANL and neighboring Pueblos. [Tewa Women United](https://tewawomenunited.org/) (TWU) took a position alongside many other concerned citizens and organizations opposing the FTWC venting and started a petition on Change.org called [“Protect Vulnerable New Mexico Communities: Halt Radioactive Tritium Release from LANL,”](https://www.change.org/p/protect-vulnerable-nm-communities-halt-radioactive-tritium-release-from-lanl) that accumulated 3,112 signatures that helped postpone the proposed venting on April 1st 2020. The All Pueblo Council of Governors also released a press release on March, 30th in opposition that alluded to the lack of tribal consultation as well as the lack of capacity in tribal governments due to COVID19.

The All Pueblo Council of Governers is set to give public comment to the NM Hazardous Waste Committee Meeting on September, 9th. It’s been stated that the New Mexico Environmental Department (NMED) and NM Hazardous Waste Board (NM HWB) do not oversee radiological contamination from LANL and that all radiological contamination remediation and radiological release approvals are under the regulatory authority of the Department of Energy (DOE). Even though it is the responsibility of NMED to ensure safety regulations for New Mexico citizens. In 2009 DOE enacted a policy, [Order 144.1](https://www.energy.gov/sites/prod/files/DOE%20O%20144.1.pdf), to ensure responsible interactions and consultation with sovereign tribal nations that we believe aren\'t being upheld.

', + supplemental_text: + '

Caste-oppressed students and staff deserve protection—yet Rutgers University continues to delay adopting crucial caste protections in its anti-discrimination policy. This hesitation comes after pressure from far-right nationalist groups that aim to erase the realities of caste-based harm.

In August 2024, the Rutgers Task Force on Caste Discrimination recommended adding caste as a protected category after collecting powerful testimony from affected community members. These recommendations are a critical step toward equity but remain stalled.

It’s time to demand action! Let’s ensure Rutgers doesn’t back down in the face of opposition. Flood the administration’s inboxes today and call for the immediate adoption of caste protections. Together, we can build a campus where no one has to endure caste discrimination.

', + representatives: JSON.stringify([ + { + name: 'Stephen Hoffman', + title: 'LANL SWEIS Document Manager, DOE/NNSA ', + photoUrl: 'https://imgs.search.brave.com/G46oqr3VnummnoFmkqT_NqalvvWvKQxpoX-EJITKqGQ/rs:fit:860:0:0:0/g:ce/aHR0cHM6Ly9uYXRp/b25hbG1hZ2xhYi5v/cmcvaW1hZ2VzL2xh/eW91dC9sb3MtYWxh/bW9zLWxvZ28uanBn/P2Q9MjAyMzAyMDc', + address_line1: '3747 West Jemez Road ', + address_line2: '', + address_city: 'Los Alamos', + address_state: 'NM', + address_zip: '87544', + address_country: 'US', + email: 'lanlsweis@nnsa.doe.gov' + } + ]), + assets: JSON.stringify({ + campaign_logo: 'https://i.imgur.com/0I80XGh.png', + campaign_background: 'https://media.assettype.com/freepressjournal/2024-09-04/i722yxsy/lg_NR15OldQueensGate0889_edit.jpg?rect=0%2C0%2C3900%2C2194&w=1200&auto=format%2Ccompress&ogImage=true', + infographic: 'https://i.imgur.com/I7E3J5Q.png', 'campaign-img-1': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ-yngrxizvU5kAZ3CP9-iQnn1OD14eXkpeXUYo96KOL6sg19Icwoes_JYlm_a61pzAcRE&usqp=CAU', 'campaign-img-2': 'https://images-prod.gothamist.com/images/GettyImages-1481222828.width-1000.jpg', 'campaign-img-3': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS2X0OYEKhzrxmyMymuEaqDUIq0jDakYX4i4jaqRI3AUs0svGfcNDbpdatY4WUD6LMPRqg&usqp=CAU' diff --git a/src/components/SearchReps.vue b/src/components/SearchReps.vue index 7df442fba..2959e3ae2 100644 --- a/src/components/SearchReps.vue +++ b/src/components/SearchReps.vue @@ -164,9 +164,16 @@
+ class="text-p pa-4" + > +
+ infographic for campaign +
Vue logo diff --git a/src/router/index.js b/src/router/index.js index b03d8020f..0f4472f4d 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -12,13 +12,33 @@ const routes = [ { path: '/', name: 'Home', - component: Home + component: () => import('../views/Campaign.vue'), + children: [ + { + path: 'postalcode/:postalCode?', + name: 'Reps', + component: SearchReps, + props: true, + children: [ + { + path: 'member/:member', + component: RepresentativeCard, + name: 'RepClick', + props: true + } + ] + } + ] }, { path: '/about', name: 'About', component: () => import('../views/About.vue') }, + /* Some campaigns have a lot of user friction when they interact with + the original landing page, so we are going to try to link to directly + to the campaigns page instead. + I will leave the original entry here so it's easy to undo later. { path: '/campaign/:campaignId', name: 'Campaign', @@ -40,6 +60,7 @@ const routes = [ } ] }, + */ { path: '/complete', name: 'CompletePage', From 6427cb4672a589c93cddf34b9912dcdf94cb76cb Mon Sep 17 00:00:00 2001 From: Glenn Date: Sat, 8 Mar 2025 19:01:34 -0600 Subject: [PATCH 20/21] linting --- script/stringify.js | 14 ++--- ...817143934_create_letter_templates_table.js | 9 ++-- .../01-seed-letter_templates-table.js | 3 +- .../development/02-seed-campaigns-table.js | 51 ++++++++++++------- src/components/SearchReps.vue | 19 +++---- 5 files changed, 55 insertions(+), 41 deletions(-) diff --git a/script/stringify.js b/script/stringify.js index 7cdff1315..35102da8d 100644 --- a/script/stringify.js +++ b/script/stringify.js @@ -15,16 +15,18 @@ const reps = JSON.stringify([ ]) */ - const assets = JSON.stringify({ campaign_logo: 'https://i.imgur.com/0I80XGh.png', - campaign_background: 'https://media.assettype.com/freepressjournal/2024-09-04/i722yxsy/lg_NR15OldQueensGate0889_edit.jpg?rect=0%2C0%2C3900%2C2194&w=1200&auto=format%2Ccompress&ogImage=true', + campaign_background: + 'https://media.assettype.com/freepressjournal/2024-09-04/i722yxsy/lg_NR15OldQueensGate0889_edit.jpg?rect=0%2C0%2C3900%2C2194&w=1200&auto=format%2Ccompress&ogImage=true', infographic: 'https://i.imgur.com/I7E3J5Q.png', - 'campaign-img-1': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ-yngrxizvU5kAZ3CP9-iQnn1OD14eXkpeXUYo96KOL6sg19Icwoes_JYlm_a61pzAcRE&usqp=CAU', - 'campaign-img-2': 'https://images-prod.gothamist.com/images/GettyImages-1481222828.width-1000.jpg', - 'campaign-img-3': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS2X0OYEKhzrxmyMymuEaqDUIq0jDakYX4i4jaqRI3AUs0svGfcNDbpdatY4WUD6LMPRqg&usqp=CAU' + 'campaign-img-1': + 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ-yngrxizvU5kAZ3CP9-iQnn1OD14eXkpeXUYo96KOL6sg19Icwoes_JYlm_a61pzAcRE&usqp=CAU', + 'campaign-img-2': + 'https://images-prod.gothamist.com/images/GettyImages-1481222828.width-1000.jpg', + 'campaign-img-3': + 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS2X0OYEKhzrxmyMymuEaqDUIq0jDakYX4i4jaqRI3AUs0svGfcNDbpdatY4WUD6LMPRqg&usqp=CAU' }) - //console.log(reps) console.log(assets) diff --git a/server/db/migrations/20240817143934_create_letter_templates_table.js b/server/db/migrations/20240817143934_create_letter_templates_table.js index eef599aed..f28f55008 100644 --- a/server/db/migrations/20240817143934_create_letter_templates_table.js +++ b/server/db/migrations/20240817143934_create_letter_templates_table.js @@ -12,11 +12,10 @@ module.exports = { await knex.schema.alterTable('letters', (table) => { table.integer('letter_template_id').unsigned() table.foreign('letter_template_id').references('letter_templates.id') - table - .enu('delivery_method', ['email', 'snail_mail'], { - useNative: true, - enumName: 'delivery_methods' - }) + table.enu('delivery_method', ['email', 'snail_mail'], { + useNative: true, + enumName: 'delivery_methods' + }) table.string('email') }) diff --git a/server/db/seeds/development/01-seed-letter_templates-table.js b/server/db/seeds/development/01-seed-letter_templates-table.js index 1fc2c066c..920670724 100644 --- a/server/db/seeds/development/01-seed-letter_templates-table.js +++ b/server/db/seeds/development/01-seed-letter_templates-table.js @@ -43,7 +43,8 @@ module.exports = { { id: 3, name: 'Pueblo Action Alliance Los Alamos Campaign', - subject: 'Halt Los Alamos National Lab’s Flanged Tritium Waste Container (FTWC) Venting in Pueblo Communities', + subject: + 'Halt Los Alamos National Lab’s Flanged Tritium Waste Container (FTWC) Venting in Pueblo Communities', merge_variables: {}, html: '

Dear Mr. Hoffman,

\

 

\ diff --git a/server/db/seeds/development/02-seed-campaigns-table.js b/server/db/seeds/development/02-seed-campaigns-table.js index 21b29d340..b03b08850 100644 --- a/server/db/seeds/development/02-seed-campaigns-table.js +++ b/server/db/seeds/development/02-seed-campaigns-table.js @@ -96,18 +96,20 @@ module.exports = { name: 'Protect Caste Equity at Rutgers University', cause: 'Civic Rights', type: 'Grant', - page_url: 'https://rutgersaaup.org/wp-content/uploads/2024/08/Rutgers-Caste-Report-August-2024.pdf', + page_url: + 'https://rutgersaaup.org/wp-content/uploads/2024/08/Rutgers-Caste-Report-August-2024.pdf', letter_template_id: 2, - campaign_tagline: - 'URGE RUTGERS TO PRIORITIZE CASTE EQUITY', - campaign_text: '

We applaud Rutgers University for taking a crucial step toward addressing caste inequity through the recent University Task Force Report on Caste Discrimination in Higher Education and at Rutgers Global caste systems enforce discrimination through inherited social status. They are a systemic injustice that has long been overlooked in the United States, despite its prevalence in many American institutions including higher education. That is why the findings of this report are so crucial. By recommending to add caste as a protected category, Rutgers has an opportunity to lead the way in creating equitable spaces for all, especially for caste-oppressed faculty, students, and workers who experience this bias.

The testimonies presented in Rutgers’ task force report are a powerful reminder of the urgent need to address caste-based exclusion, harassment, and inequities in higher education. Caste is not an abstract concept; it is a harsh reality for millions. Caste discrimination spans across industries and includes bullying, harassment, bias, wage theft, sexual harassment, and even trafficking. Caste-oppressed individuals have also been denied rental housing upon the discovery of their caste identity. This issue has gained significant attention in New Jersey following human trafficking allegations against the BAPS temples, where caste-oppressed workers were held against their will and paid just a dollar an hour under inhumane conditions

In New Jersey there are many communities who suffer caste discrimination in their communities from Africa, South Asia, Asia, and Indigenous residents of the state. Students, faculty and staff from these backgrounds must be able to access the campus as a place of learning and as a workplace free from discrimination and harm.

From workplace discrimination to campus bullying, the insidious impacts of caste privilege have been well-documented by marginalized communities, In our own 2016 report Caste in the United States we have found caste oppressed people face alarming discrimination and harassment with 1 in 4 facing physical and verbal assault, 1 in 3 education discrimination and 2 out 3 workplace discrimination.

As a U.S.-based civil rights group we urge Rutgers’ administration **to fully adopt the task force’s recommendations and implement robust enforcement mechanisms.** This includes education on caste equity for students, staff, and faculty and meaningful support for those who come forward with experiences of caste-based harm.

As Rutgers advances this work, we caution against narratives that dismiss caste protections as “anti-Hindu” or as targeting specific communities. Such arguments weaponize bad faith arguments and privilege to silence Dalit voices and maintain systems of oppression. Caste is found across multiple geographies and faiths and it must be addressed as its own system of exclusion. We believe in fostering dialogue that centers the experiences of the most vulnerable while rejecting extremist  rhetoric that masquerades falsely as a defense of cultural identity.

Rutgers’ initiative is part of a broader, necessary movement to confront caste oppression in the United States. We look forward to standing alongside other universities and institutions in their journey toward caste equity. Together, we can build communities where everyone can thrive with dignity and equal opportunity.

In solidarity,

Equality Labs

', + campaign_tagline: 'URGE RUTGERS TO PRIORITIZE CASTE EQUITY', + campaign_text: + '

We applaud Rutgers University for taking a crucial step toward addressing caste inequity through the recent University Task Force Report on Caste Discrimination in Higher Education and at Rutgers Global caste systems enforce discrimination through inherited social status. They are a systemic injustice that has long been overlooked in the United States, despite its prevalence in many American institutions including higher education. That is why the findings of this report are so crucial. By recommending to add caste as a protected category, Rutgers has an opportunity to lead the way in creating equitable spaces for all, especially for caste-oppressed faculty, students, and workers who experience this bias.

The testimonies presented in Rutgers’ task force report are a powerful reminder of the urgent need to address caste-based exclusion, harassment, and inequities in higher education. Caste is not an abstract concept; it is a harsh reality for millions. Caste discrimination spans across industries and includes bullying, harassment, bias, wage theft, sexual harassment, and even trafficking. Caste-oppressed individuals have also been denied rental housing upon the discovery of their caste identity. This issue has gained significant attention in New Jersey following human trafficking allegations against the BAPS temples, where caste-oppressed workers were held against their will and paid just a dollar an hour under inhumane conditions

In New Jersey there are many communities who suffer caste discrimination in their communities from Africa, South Asia, Asia, and Indigenous residents of the state. Students, faculty and staff from these backgrounds must be able to access the campus as a place of learning and as a workplace free from discrimination and harm.

From workplace discrimination to campus bullying, the insidious impacts of caste privilege have been well-documented by marginalized communities, In our own 2016 report Caste in the United States we have found caste oppressed people face alarming discrimination and harassment with 1 in 4 facing physical and verbal assault, 1 in 3 education discrimination and 2 out 3 workplace discrimination.

As a U.S.-based civil rights group we urge Rutgers’ administration **to fully adopt the task force’s recommendations and implement robust enforcement mechanisms.** This includes education on caste equity for students, staff, and faculty and meaningful support for those who come forward with experiences of caste-based harm.

As Rutgers advances this work, we caution against narratives that dismiss caste protections as “anti-Hindu” or as targeting specific communities. Such arguments weaponize bad faith arguments and privilege to silence Dalit voices and maintain systems of oppression. Caste is found across multiple geographies and faiths and it must be addressed as its own system of exclusion. We believe in fostering dialogue that centers the experiences of the most vulnerable while rejecting extremist  rhetoric that masquerades falsely as a defense of cultural identity.

Rutgers’ initiative is part of a broader, necessary movement to confront caste oppression in the United States. We look forward to standing alongside other universities and institutions in their journey toward caste equity. Together, we can build communities where everyone can thrive with dignity and equal opportunity.

In solidarity,

Equality Labs

', supplemental_text: '

Caste-oppressed students and staff deserve protection—yet Rutgers University continues to delay adopting crucial caste protections in its anti-discrimination policy. This hesitation comes after pressure from far-right nationalist groups that aim to erase the realities of caste-based harm.

In August 2024, the Rutgers Task Force on Caste Discrimination recommended adding caste as a protected category after collecting powerful testimony from affected community members. These recommendations are a critical step toward equity but remain stalled.

It’s time to demand action! Let’s ensure Rutgers doesn’t back down in the face of opposition. Flood the administration’s inboxes today and call for the immediate adoption of caste protections. Together, we can build a campus where no one has to endure caste discrimination.

', representatives: JSON.stringify([ { name: 'President Jonathan Holloway', title: 'President, Rutgers University', - photoUrl: 'https://www.rutgers.edu/sites/default/files/styles/3x4_one_third_full_1024_1x/public/2020-07/pro_NR20HollowayJonathan1819.jpg?h=ef631461&itok=uRWXEI4G', + photoUrl: + 'https://www.rutgers.edu/sites/default/files/styles/3x4_one_third_full_1024_1x/public/2020-07/pro_NR20HollowayJonathan1819.jpg?h=ef631461&itok=uRWXEI4G', address_line1: '7 College Avenue', address_line2: '2nd Floor', address_city: 'New Brunswick', @@ -119,7 +121,8 @@ module.exports = { { name: 'Anna (Enobong) Branch', title: 'Senior Vice President for University Equity and Inclusion', - photoUrl: 'https://www.rutgers.edu/sites/default/files/styles/3x4_one_third_full_1024_1x/public/2020-09/pro_Ann_Branch.jpg?h=3dfac914&itok=rA6GxwC_', + photoUrl: + 'https://www.rutgers.edu/sites/default/files/styles/3x4_one_third_full_1024_1x/public/2020-09/pro_Ann_Branch.jpg?h=3dfac914&itok=rA6GxwC_', address_line1: '106 Sommerset Street', address_line2: '7th Floor', address_city: 'New Brunswick', @@ -131,7 +134,8 @@ module.exports = { { name: 'Prabhas Moghe', title: 'Executive Vice President for Academic Affairs at Rutgers', - photoUrl: 'https://www.rutgers.edu/sites/default/files/styles/max_width_embed_default_2x/public/2020-09/pro_Prabhas_Moghe.jpg?itok=dLd3TLhW', + photoUrl: + 'https://www.rutgers.edu/sites/default/files/styles/max_width_embed_default_2x/public/2020-09/pro_Prabhas_Moghe.jpg?itok=dLd3TLhW', address_line1: '7 College Avenue', address_line2: '2nd Floor', address_city: 'New Brunswick', @@ -143,11 +147,15 @@ module.exports = { ]), assets: JSON.stringify({ campaign_logo: 'https://i.imgur.com/0I80XGh.png', - campaign_background: 'https://media.assettype.com/freepressjournal/2024-09-04/i722yxsy/lg_NR15OldQueensGate0889_edit.jpg?rect=0%2C0%2C3900%2C2194&w=1200&auto=format%2Ccompress&ogImage=true', + campaign_background: + 'https://media.assettype.com/freepressjournal/2024-09-04/i722yxsy/lg_NR15OldQueensGate0889_edit.jpg?rect=0%2C0%2C3900%2C2194&w=1200&auto=format%2Ccompress&ogImage=true', infographic: 'https://i.imgur.com/I7E3J5Q.png', - 'campaign-img-1': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ-yngrxizvU5kAZ3CP9-iQnn1OD14eXkpeXUYo96KOL6sg19Icwoes_JYlm_a61pzAcRE&usqp=CAU', - 'campaign-img-2': 'https://images-prod.gothamist.com/images/GettyImages-1481222828.width-1000.jpg', - 'campaign-img-3': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS2X0OYEKhzrxmyMymuEaqDUIq0jDakYX4i4jaqRI3AUs0svGfcNDbpdatY4WUD6LMPRqg&usqp=CAU' + 'campaign-img-1': + 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ-yngrxizvU5kAZ3CP9-iQnn1OD14eXkpeXUYo96KOL6sg19Icwoes_JYlm_a61pzAcRE&usqp=CAU', + 'campaign-img-2': + 'https://images-prod.gothamist.com/images/GettyImages-1481222828.width-1000.jpg', + 'campaign-img-3': + 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS2X0OYEKhzrxmyMymuEaqDUIq0jDakYX4i4jaqRI3AUs0svGfcNDbpdatY4WUD6LMPRqg&usqp=CAU' }) }, { @@ -156,18 +164,21 @@ module.exports = { name: 'Pueblo Action Alliance', cause: 'Civic Rights', type: 'Grant', - page_url: 'https://rutgersaaup.org/wp-content/uploads/2024/08/Rutgers-Caste-Report-August-2024.pdf', + page_url: + 'https://rutgersaaup.org/wp-content/uploads/2024/08/Rutgers-Caste-Report-August-2024.pdf', letter_template_id: 3, campaign_tagline: 'Halt Los Alamos National Lab’s Flanged Tritium Waste Container (FTWC) Venting in Pueblo Communities', - campaign_text: '

Los Alamos National Labs (LANL) has proposed the Flanged Tritium Waste Container venting, four containers, near LANL and neighboring Pueblos. [Tewa Women United](https://tewawomenunited.org/) (TWU) took a position alongside many other concerned citizens and organizations opposing the FTWC venting and started a petition on Change.org called [“Protect Vulnerable New Mexico Communities: Halt Radioactive Tritium Release from LANL,”](https://www.change.org/p/protect-vulnerable-nm-communities-halt-radioactive-tritium-release-from-lanl) that accumulated 3,112 signatures that helped postpone the proposed venting on April 1st 2020. The All Pueblo Council of Governors also released a press release on March, 30th in opposition that alluded to the lack of tribal consultation as well as the lack of capacity in tribal governments due to COVID19.

The All Pueblo Council of Governers is set to give public comment to the NM Hazardous Waste Committee Meeting on September, 9th. It’s been stated that the New Mexico Environmental Department (NMED) and NM Hazardous Waste Board (NM HWB) do not oversee radiological contamination from LANL and that all radiological contamination remediation and radiological release approvals are under the regulatory authority of the Department of Energy (DOE). Even though it is the responsibility of NMED to ensure safety regulations for New Mexico citizens. In 2009 DOE enacted a policy, [Order 144.1](https://www.energy.gov/sites/prod/files/DOE%20O%20144.1.pdf), to ensure responsible interactions and consultation with sovereign tribal nations that we believe aren\'t being upheld.

', + campaign_text: + '

Los Alamos National Labs (LANL) has proposed the Flanged Tritium Waste Container venting, four containers, near LANL and neighboring Pueblos. [Tewa Women United](https://tewawomenunited.org/) (TWU) took a position alongside many other concerned citizens and organizations opposing the FTWC venting and started a petition on Change.org called [“Protect Vulnerable New Mexico Communities: Halt Radioactive Tritium Release from LANL,”](https://www.change.org/p/protect-vulnerable-nm-communities-halt-radioactive-tritium-release-from-lanl) that accumulated 3,112 signatures that helped postpone the proposed venting on April 1st 2020. The All Pueblo Council of Governors also released a press release on March, 30th in opposition that alluded to the lack of tribal consultation as well as the lack of capacity in tribal governments due to COVID19.

The All Pueblo Council of Governers is set to give public comment to the NM Hazardous Waste Committee Meeting on September, 9th. It’s been stated that the New Mexico Environmental Department (NMED) and NM Hazardous Waste Board (NM HWB) do not oversee radiological contamination from LANL and that all radiological contamination remediation and radiological release approvals are under the regulatory authority of the Department of Energy (DOE). Even though it is the responsibility of NMED to ensure safety regulations for New Mexico citizens. In 2009 DOE enacted a policy, [Order 144.1](https://www.energy.gov/sites/prod/files/DOE%20O%20144.1.pdf), to ensure responsible interactions and consultation with sovereign tribal nations that we believe aren\'t being upheld.

', supplemental_text: '

Caste-oppressed students and staff deserve protection—yet Rutgers University continues to delay adopting crucial caste protections in its anti-discrimination policy. This hesitation comes after pressure from far-right nationalist groups that aim to erase the realities of caste-based harm.

In August 2024, the Rutgers Task Force on Caste Discrimination recommended adding caste as a protected category after collecting powerful testimony from affected community members. These recommendations are a critical step toward equity but remain stalled.

It’s time to demand action! Let’s ensure Rutgers doesn’t back down in the face of opposition. Flood the administration’s inboxes today and call for the immediate adoption of caste protections. Together, we can build a campus where no one has to endure caste discrimination.

', representatives: JSON.stringify([ { name: 'Stephen Hoffman', title: 'LANL SWEIS Document Manager, DOE/NNSA ', - photoUrl: 'https://imgs.search.brave.com/G46oqr3VnummnoFmkqT_NqalvvWvKQxpoX-EJITKqGQ/rs:fit:860:0:0:0/g:ce/aHR0cHM6Ly9uYXRp/b25hbG1hZ2xhYi5v/cmcvaW1hZ2VzL2xh/eW91dC9sb3MtYWxh/bW9zLWxvZ28uanBn/P2Q9MjAyMzAyMDc', + photoUrl: + 'https://imgs.search.brave.com/G46oqr3VnummnoFmkqT_NqalvvWvKQxpoX-EJITKqGQ/rs:fit:860:0:0:0/g:ce/aHR0cHM6Ly9uYXRp/b25hbG1hZ2xhYi5v/cmcvaW1hZ2VzL2xh/eW91dC9sb3MtYWxh/bW9zLWxvZ28uanBn/P2Q9MjAyMzAyMDc', address_line1: '3747 West Jemez Road ', address_line2: '', address_city: 'Los Alamos', @@ -179,11 +190,15 @@ module.exports = { ]), assets: JSON.stringify({ campaign_logo: 'https://i.imgur.com/0I80XGh.png', - campaign_background: 'https://media.assettype.com/freepressjournal/2024-09-04/i722yxsy/lg_NR15OldQueensGate0889_edit.jpg?rect=0%2C0%2C3900%2C2194&w=1200&auto=format%2Ccompress&ogImage=true', + campaign_background: + 'https://media.assettype.com/freepressjournal/2024-09-04/i722yxsy/lg_NR15OldQueensGate0889_edit.jpg?rect=0%2C0%2C3900%2C2194&w=1200&auto=format%2Ccompress&ogImage=true', infographic: 'https://i.imgur.com/I7E3J5Q.png', - 'campaign-img-1': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ-yngrxizvU5kAZ3CP9-iQnn1OD14eXkpeXUYo96KOL6sg19Icwoes_JYlm_a61pzAcRE&usqp=CAU', - 'campaign-img-2': 'https://images-prod.gothamist.com/images/GettyImages-1481222828.width-1000.jpg', - 'campaign-img-3': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS2X0OYEKhzrxmyMymuEaqDUIq0jDakYX4i4jaqRI3AUs0svGfcNDbpdatY4WUD6LMPRqg&usqp=CAU' + 'campaign-img-1': + 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ-yngrxizvU5kAZ3CP9-iQnn1OD14eXkpeXUYo96KOL6sg19Icwoes_JYlm_a61pzAcRE&usqp=CAU', + 'campaign-img-2': + 'https://images-prod.gothamist.com/images/GettyImages-1481222828.width-1000.jpg', + 'campaign-img-3': + 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS2X0OYEKhzrxmyMymuEaqDUIq0jDakYX4i4jaqRI3AUs0svGfcNDbpdatY4WUD6LMPRqg&usqp=CAU' }) } ]) diff --git a/src/components/SearchReps.vue b/src/components/SearchReps.vue index 2959e3ae2..4c778a3ed 100644 --- a/src/components/SearchReps.vue +++ b/src/components/SearchReps.vue @@ -162,18 +162,15 @@
-
-
+
+
infographic for campaign -
+ v-if="assets['infographic']" + :src="assets['infographic']" + alt="infographic for campaign" + class="infographic-img" + /> +
Vue logo Date: Wed, 11 Jun 2025 00:29:11 +0000 Subject: [PATCH 21/21] criando uma pr --- server/routes/api/checkout.js | 1 + 1 file changed, 1 insertion(+) diff --git a/server/routes/api/checkout.js b/server/routes/api/checkout.js index efbd255ca..4dd6c0276 100644 --- a/server/routes/api/checkout.js +++ b/server/routes/api/checkout.js @@ -130,6 +130,7 @@ router.post('/create-checkout-session', async (req, res) => { ) const html = Handlebars.render(letter.merge_variables, template.html) + // Using a temporary mapping here also for (const method of deliveryMethods) { // Generate a uuid so letters are idempotent