Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
8ed0172
query for name and contactId on allenites
interim17 Mar 25, 2026
e07ebd5
add @netlify/plugin-gatsby
interim17 Mar 25, 2026
6a53af4
access env variable email in contact function
interim17 Mar 25, 2026
c1c9094
use updated netlify function with validation
interim17 Mar 25, 2026
e597cda
use updated contact function for email
interim17 Mar 25, 2026
572b4f1
fix lint error in Figure component
interim17 Mar 25, 2026
3b6b0fe
use netlify email integration
interim17 Mar 26, 2026
8939dd6
pass title to email function
interim17 Mar 26, 2026
be07d1a
update netlify doc and .env.example
interim17 Mar 26, 2026
9ba9d56
generic function for building node queries
interim17 Mar 26, 2026
2e02a58
generic node query
interim17 Mar 26, 2026
b05d6d8
filter data only pages in page creation
interim17 Mar 26, 2026
3bd086f
Merge branch 'feature/contact-query' into mailgun
interim17 Mar 26, 2026
6c159d9
removed PII logging and stopped returning the full request body
interim17 Mar 26, 2026
fbfdc77
fall back to "Idea Board" default when preferred recipient lacks a co…
interim17 Mar 26, 2026
8ff479a
validate env vars in contact function, derive base url from incoming …
interim17 Mar 26, 2026
b44820c
harden sender email to prevent header injection
interim17 Mar 26, 2026
5c8b6d5
Merge branch 'feature/contact-query' into mailgun
interim17 Mar 26, 2026
5f17dba
WIP access emails from google sheet
interim17 Apr 21, 2026
3c1aa03
commit to trigger preview
interim17 Apr 21, 2026
8a1b43b
delete example env file
interim17 Apr 21, 2026
7b8ba71
delete netlify docs to test secrets issue
interim17 Apr 21, 2026
55ca5f2
Revert "delete example env file"
interim17 Apr 21, 2026
768ac5e
delete netlify doc
interim17 Apr 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ node_modules
public/
static/admin/*.bundle.*
.DS_Store
.env
yarn-error.log
gatsby-types.d.ts

Expand Down
31 changes: 31 additions & 0 deletions emails/contact/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<html>
<body
style="
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f5f5f5;
"
>
<div
style="
max-width: 600px;
margin: 24px auto;
background-color: #ffffff;
border-radius: 8px;
padding: 32px;
"
>
<h2 style="margin-top: 0;">New message from the Idea Board</h2>
<p><strong>From:</strong> {{senderName}} ({{senderEmail}})</p>
<p><strong>Regarding idea:</strong> {{ideaTitle}}</p>
<hr style="border: none; border-top: 1px solid #e0e0e0; margin: 16px 0;" />
<p>{{message}}</p>
<hr style="border: none; border-top: 1px solid #e0e0e0; margin: 16px 0;" />
<p style="font-size: 12px; color: #888;">
You can reply directly to {{senderName}} at
<a href="mailto:{{senderEmail}}">{{senderEmail}}</a>.
</p>
</div>
</body>
</html>
25 changes: 22 additions & 3 deletions gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const {
stringWithDefault,
resolveToArray,
resourceQuery,
alleniteQuery,
} = require("./gatsby/utils/gatsby-resolver-utils");
const {
RESOURCES_GATSBY_NODE_KEY,
Expand Down Expand Up @@ -70,7 +71,24 @@ exports.createResolvers = ({ reporter, createResolvers }) => {
),
},
authors: {
resolve: (source) => resolveToArray(source.authors),
resolve: async (source, _args, context) => {
const names = resolveToArray(source.authors);
const results = await Promise.all(
names
.filter(Boolean)
.map((name) =>
context.nodeModel.findOne(alleniteQuery(name)),
),
);
return results.filter(Boolean);
},
},
primaryContact: {
resolve: async (source, _args, context) => {
const query = alleniteQuery(source.primaryContact);
if (!query) return null;
return context.nodeModel.findOne(query);
},
},
title: {
resolve: (source) =>
Expand Down Expand Up @@ -128,8 +146,9 @@ exports.createPages = ({ actions, graphql }) => {

// Create pages for any markdown files that are configured to have their
// own node type (e.g. Resource) based on their templateKey.
const typedNodePages = Object.keys(TEMPLATE_KEY_TO_TYPE).map(
(templateKey) => {
const typedNodePages = Object.keys(TEMPLATE_KEY_TO_TYPE)
.filter((templateKey) => !DATA_ONLY_PAGES.includes(templateKey))
.map((templateKey) => {
const nodeKey = TEMPLATE_KEY_TO_TYPE[templateKey];
const allKeyString = `all${nodeKey}`;
return graphql(`
Expand Down
3 changes: 3 additions & 0 deletions gatsby/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const PROGRAM_TEMPLATE_KEY = `program`;
const RESOURCES_TEMPLATE_KEY = `resource`;

const RESOURCES_GATSBY_NODE_KEY = `Resource`;
const ALLENITE_GATSBY_NODE_KEY = `Allenite`;
const MARKDOWN_REMARK_GATSBY_NODE_KEY = `MarkdownRemark`;

/**
Expand All @@ -14,6 +15,7 @@ const MARKDOWN_REMARK_GATSBY_NODE_KEY = `MarkdownRemark`;
*/
const TEMPLATE_KEY_TO_TYPE = {
[RESOURCES_TEMPLATE_KEY]: RESOURCES_GATSBY_NODE_KEY,
[ALLENITE_TEMPLATE_KEY]: ALLENITE_GATSBY_NODE_KEY,
};
module.exports = {
ALLENITE_TEMPLATE_KEY,
Expand All @@ -22,4 +24,5 @@ module.exports = {
MARKDOWN_REMARK_GATSBY_NODE_KEY,
TEMPLATE_KEY_TO_TYPE,
RESOURCES_GATSBY_NODE_KEY,
ALLENITE_GATSBY_NODE_KEY,
};
15 changes: 12 additions & 3 deletions gatsby/schema/base.gql
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ type Frontmatter {
description: String
draft: Boolean
tags: [String!]
authors: [String!]!
authors: [Allenite!]!
nextSteps: String
program: [String!]
publication: String
introduction: String
resources: [Resource!]!
primaryContact: String
primaryContact: Allenite
}

type Resource implements Node {
Expand All @@ -35,4 +35,13 @@ type Resource implements Node {
date: Date @dateformat
tags: [String!]
draft: Boolean
}
}

type Allenite implements Node {
slug: String!
name: String!
contactId: String
position: String
contact: String
program: [String!]
}
22 changes: 15 additions & 7 deletions gatsby/utils/gatsby-resolver-utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const {
RESOURCES_TEMPLATE_KEY,
TEMPLATE_KEY_TO_TYPE,
ALLENITE_TEMPLATE_KEY,
} = require("../constants");
const slugify = require("slugify");

Expand Down Expand Up @@ -47,23 +48,30 @@ const resolveSlug = (id, directory) => {
};

/**
* Builds a nodeModel query for a single Resource node by display name.
* Returns null if the name can't be slugified (falsy input).
* @param {string|null|undefined} name - The resource's name (e.g., "Software Y")
* @returns {{ query: object, type: string } | null}
* Builds a nodeModel query for a single node by display name and template key.
* Uses slugs in place of names to prevent namespace collisions when querying
* via Gatsby's nodeModel. Returns null if the name can't be slugified (falsy input).
* @param {string|null|undefined} name - The node's display name (e.g., "Software Y", "Jane Smith")
* @param {string} templateKey - The template key used for slug resolution and type lookup (e.g., RESOURCES_TEMPLATE_KEY)
* @returns {{ query: object, type: string } | null} A nodeModel-compatible query/type pair, or null
*/
const resourceQuery = (name) => {
const slug = resolveSlug(name, RESOURCES_TEMPLATE_KEY);
const buildNodeQuery = (name, templateKey) => {
const slug = resolveSlug(name, templateKey);
if (!slug) return null;
return {
query: { filter: { slug: { eq: slug } } },
type: TEMPLATE_KEY_TO_TYPE[RESOURCES_TEMPLATE_KEY], // "Resource"
type: TEMPLATE_KEY_TO_TYPE[templateKey],
};
};

const resourceQuery = (name) => buildNodeQuery(name, RESOURCES_TEMPLATE_KEY);
const alleniteQuery = (name) => buildNodeQuery(name, ALLENITE_TEMPLATE_KEY);

module.exports = {
stringWithDefault,
resolveToArray,
resolveSlug,
resourceQuery,
alleniteQuery,
buildNodeQuery,
};
4 changes: 4 additions & 0 deletions netlify.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
[build]
publish = "public"
command = "npm run build"
package = "@netlify/plugin-gatsby"
[[plugins]]
package = "@netlify/plugin-emails"

[build.environment]
NODE_VERSION = "22.16.0"
YARN_VERSION = "1.22.4"
Expand Down
Loading