Skip to content

Commit f0b5f81

Browse files
committed
Resume stylings
1 parent 2024b95 commit f0b5f81

37 files changed

Lines changed: 805 additions & 1061 deletions

.env.example

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,18 @@ CRON_SECRET="<cron_secret_here>"
3838
PUBLIC_GOOGLE_MAPS_API_KEY="<api_key_here>"
3939
PUBLIC_GOOGLE_MAP_ID="<map_id>"
4040

41+
##
42+
# HubSpot CRM configuration
43+
# Provided by Vercel to Function so no need to bundle with PUBLIC_ prefix
44+
##
45+
46+
# Environment variable
47+
HUBSPOT_HTTP_PORT="9012" # development env only for WireMock container
48+
# Environment secret
49+
HUBSPOT_ACCESS_TOKEN="<access_token_here>"
50+
# Environment variable — ID of the static ILS segment used for newsletter subscribers
51+
HUBSPOT_NEWSLETTER_LIST_ID="<list_id_here>"
52+
4153
##
4254
# SMTP remailer
4355
# Provided by Vercel to Function so no need to bundle with PUBLIC_ prefix

src/components/Footer/index.astro

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
import contactData from '@content/contact.json'
2+
import { companyContactData } from '@lib/content/contactData'
33
import { formatPhoneNumber } from '@components/Footer/server'
44
import Avatar from '@components/Avatar/index.astro'
55
import BugReporter from '@components/BugReporter/index.astro'
@@ -80,59 +80,59 @@ const footerTextLinkClasses = [
8080
<Avatar name="Kevin Brown" />
8181
</div>
8282
{/* Mobile: company name */}
83-
<h2 class="font-bold text-2xl sm:hidden">{contactData.company.name}</h2>
83+
<h2 class="font-bold text-2xl sm:hidden">{companyContactData.name}</h2>
8484
</div>
8585
{/* Address and Phone Numbers Block */}
8686
<address class="mt-3 text-base sm:mt-0">
8787
{/* Desktop: company name */}
88-
<h2 class="hidden font-bold text-2xl sm:block">{contactData.company.name}</h2>
88+
<h2 class="hidden font-bold text-2xl sm:block">{companyContactData.name}</h2>
8989
{/* Street Address */}
9090
<div class="mt-2 sm:ml-1">
91-
<p>{contactData.company.address}</p>
91+
<p>{companyContactData.address}</p>
9292
<p>
93-
{contactData.company.city}, {contactData.company.state}
94-
{contactData.company.index}
93+
{companyContactData.city}, {companyContactData.state}
94+
{companyContactData.index}
9595
</p>
9696
</div>
9797
{/* Email Address */}
9898
<p class="hyphens-none">
9999
<a
100-
href={`mailto:${contactData.company.email}`}
100+
href={`mailto:${companyContactData.email}`}
101101
class:list={[
102102
'inline-flex min-h-6 items-center align-middle',
103103
'hover:text-secondary hover:decoration-secondary focus:text-secondary focus:decoration-secondary',
104104
'focus-visible:outline-2 focus-visible:outline-spotlight focus-visible:outline-offset-2',
105105
]}
106106
>
107-
{contactData.company.email}
107+
{companyContactData.email}
108108
</a>
109109
</p>
110110
{/* Toll Free Telephone Number */}
111111
<p itemprop="telephone">
112112
<a
113-
href={`tel:${contactData.company.telephoneTollFree}`}
113+
href={`tel:${companyContactData.telephoneTollFree}`}
114114
rel="nofollow"
115115
class:list={[
116116
'inline-flex min-h-6 items-center align-middle',
117117
'hover:text-secondary hover:decoration-secondary focus:text-secondary focus:decoration-secondary',
118118
'focus-visible:outline-2 focus-visible:outline-spotlight focus-visible:outline-offset-2',
119119
]}
120120
>
121-
Toll Free {formatPhoneNumber(contactData.company.telephoneTollFree)}
121+
Toll Free {formatPhoneNumber(companyContactData.telephoneTollFree)}
122122
</a>
123123
</p>
124124
{/* Local Telephone Number */}
125125
<p itemprop="telephone">
126126
<a
127-
href={`tel:${contactData.company.telephoneLocal}`}
127+
href={`tel:${companyContactData.telephoneLocal}`}
128128
rel="nofollow"
129129
class:list={[
130130
'inline-flex min-h-6 items-center align-middle',
131131
'hover:text-secondary hover:decoration-secondary focus:text-secondary focus:decoration-secondary',
132132
'focus-visible:outline-2 focus-visible:outline-spotlight focus-visible:outline-offset-2',
133133
]}
134134
>
135-
Local {formatPhoneNumber(contactData.company.telephoneLocal)}
135+
Local {formatPhoneNumber(companyContactData.telephoneLocal)}
136136
</a>
137137
</p>
138138
</address>
@@ -161,7 +161,7 @@ const footerTextLinkClasses = [
161161
<nav class:list={["mt-5", styles.footerSocial]} aria-label="Social links">
162162
<ul class="grid list-none gap-x-4 gap-y-3 p-0 sm:mb-0 sm:mt-0 sm:mx-0 lg:grid-cols-2">
163163
{
164-
contactData.company.social
164+
companyContactData.social
165165
.sort((a, b) => a.order - b.order)
166166
.map(social => (
167167
<li class="list-none">

src/components/Head/Meta.astro

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
import contactData from '@content/contact.json'
2+
import { companyContactData } from '@lib/content/contactData'
33
import { absoluteUrl } from '@components/scripts/utils'
44
import { applyRenderSentryContext } from '@lib/sentry/renderContext'
55
import { getMetaThemeData } from '@components/Head/server/meta'
@@ -60,7 +60,7 @@ applyRenderSentryContext({
6060
pageTitle,
6161
noindex,
6262
contentType,
63-
pageDescriptionLength: (pageDescription || contactData.company.description).length,
63+
pageDescriptionLength: (pageDescription || companyContactData.description).length,
6464
canonicalUrl: Astro.url?.href,
6565
resolvedSiteUrl: site,
6666
},
@@ -69,8 +69,8 @@ applyRenderSentryContext({
6969

7070
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
7171
<meta name="viewport" content="width=device-width, initial-scale=1" />
72-
<meta name="description" content={pageDescription || contactData.company.description} />
73-
<meta name="author" content={contactData.company.author.name} />
72+
<meta name="description" content={pageDescription || companyContactData.description} />
73+
<meta name="author" content={companyContactData.author.name} />
7474
<meta name="robots" content={noindex ? 'noindex, nofollow' : 'index, follow'} />
7575
<Seo
7676
path={path}
@@ -84,7 +84,7 @@ applyRenderSentryContext({
8484
{/* Open Graph meta tags for Twitter and Facebook social shares */}
8585
<Social
8686
title={pageTitle}
87-
description={pageDescription || contactData.company.description}
87+
description={pageDescription || companyContactData.description}
8888
path={path}
8989
/>
9090
{/* JSON-LD Structured Data for search engines */}
@@ -120,7 +120,7 @@ applyRenderSentryContext({
120120
type="application/rss+xml"
121121
rel="alternate"
122122
href={absoluteUrl('rss.xml', site)}
123-
title={`RSS Feed for ${contactData.company.name}`}
123+
title={`RSS Feed for ${companyContactData.name}`}
124124
/>
125125
{/* Web App Manifest */}
126126
<link rel="manifest" href="/manifest.json" />

src/components/Head/Social.astro

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55
import { absoluteUrl } from '@components/scripts/utils'
66
import { getSocialImageLink, resolveSiteUrl } from '@components/Head/server'
7-
import contactData from '@content/contact.json'
7+
import { companyContactData } from '@lib/content/contactData'
88
99
export interface Props {
1010
description: string
@@ -24,7 +24,7 @@ const site = resolveSiteUrl(Astro)
2424
<meta property="og:image:alt" content={`Social card for ${title}`} />
2525
{/* Canonical URL of the page */}
2626
<meta property="og:url" content={absoluteUrl(path, site)} />
27-
<meta property="og:site_name" content={contactData.company.name} />
27+
<meta property="og:site_name" content={companyContactData.name} />
2828

2929
{/* Twitter metadata */}
3030
<meta name="twitter:card" content="summary_large_image" />

src/components/Head/server/structuredData.ts

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import type {
99
WebSite,
1010
WithContext,
1111
} from 'schema-dts'
12-
import contactData from '@content/contact.json'
12+
import { companyContactData } from '@lib/content/contactData'
1313
import { absoluteUrl } from '@components/scripts/utils/absoluteUrl'
1414
import { BuildError } from '@lib/errors/BuildError'
1515
import { getSocialImageLink, resolveSiteUrl } from '@components/Head/server'
@@ -88,7 +88,7 @@ const createSchemaContext = (params: StructuredDataParams): SchemaContext => {
8888
const site = resolveSiteUrl(astro)
8989
const normalizedPath = normalizePath(path)
9090
const canonicalUrl = astro.url?.href ?? resolveRoute(normalizedPath, site)
91-
const pageDescriptionFallback = pageDescription ?? contactData.company.description
91+
const pageDescriptionFallback = pageDescription ?? companyContactData.description
9292
const socialImageUrl = getSocialImageLink(path, site)
9393

9494
const context: SchemaContext = {
@@ -128,18 +128,18 @@ const organizationSchema: SchemaBuilder = context => {
128128
return {
129129
'@context': 'https://schema.org',
130130
'@type': 'Organization',
131-
name: contactData.company.name,
132-
url: contactData.company.url,
131+
name: companyContactData.name,
132+
url: companyContactData.url,
133133
logo: logoUrl,
134-
description: contactData.company.description,
135-
email: contactData.company.email,
134+
description: companyContactData.description,
135+
email: companyContactData.email,
136136
address: {
137137
'@type': 'PostalAddress',
138-
addressLocality: contactData.company.city,
139-
addressRegion: contactData.company.state,
140-
addressCountry: contactData.company.country,
138+
addressLocality: companyContactData.city,
139+
addressRegion: companyContactData.state,
140+
addressCountry: companyContactData.country,
141141
},
142-
sameAs: contactData.company.social.map(social => social.url),
142+
sameAs: companyContactData.social.map(social => social.url),
143143
} satisfies WithContext<Organization>
144144
}
145145

@@ -151,12 +151,12 @@ const webSiteSchema: SchemaBuilder = context => {
151151
return {
152152
'@context': 'https://schema.org',
153153
'@type': 'WebSite',
154-
name: contactData.company.name,
155-
url: contactData.company.url,
154+
name: companyContactData.name,
155+
url: companyContactData.url,
156156
description: context.pageDescription,
157157
publisher: {
158158
'@type': 'Organization',
159-
name: contactData.company.name,
159+
name: companyContactData.name,
160160
logo: resolveAssetUrl(ICON_PATH, context.site),
161161
},
162162
} satisfies WithContext<WebSite>
@@ -178,11 +178,11 @@ const articleSchema: SchemaBuilder = context => {
178178
dateModified: (context.modifiedDate ?? context.publishDate).toISOString(),
179179
author: {
180180
'@type': 'Person',
181-
name: context.author || contactData.company.author.name,
181+
name: context.author || companyContactData.author.name,
182182
},
183183
publisher: {
184184
'@type': 'Organization',
185-
name: contactData.company.name,
185+
name: companyContactData.name,
186186
logo: resolveAssetUrl(ICON_PATH, context.site),
187187
},
188188
url: context.canonicalUrl,
@@ -239,8 +239,8 @@ const serviceSchema: SchemaBuilder = context => {
239239
description: context.pageDescription,
240240
provider: {
241241
'@type': 'Organization',
242-
name: contactData.company.name,
243-
url: contactData.company.url,
242+
name: companyContactData.name,
243+
url: companyContactData.url,
244244
},
245245
url: context.canonicalUrl,
246246
} satisfies WithContext<Service>
@@ -259,9 +259,9 @@ const contactPageSchema: SchemaBuilder = context => {
259259
url: context.canonicalUrl,
260260
mainEntity: {
261261
'@type': 'Organization',
262-
name: contactData.company.name,
263-
email: contactData.company.email,
264-
url: contactData.company.url,
262+
name: companyContactData.name,
263+
email: companyContactData.email,
264+
url: companyContactData.url,
265265
},
266266
} satisfies WithContext<ContactPage>
267267
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
export type Props = {
3+
color: string
4+
classes?: string
5+
size: number
6+
accessible: boolean
7+
focusable: boolean
8+
isListMarker?: boolean
9+
id?: string
10+
}
11+
12+
const { color, classes, size, accessible, focusable, isListMarker, id } = Astro.props
13+
---
14+
15+
<svg
16+
id={id}
17+
xmlns="http://www.w3.org/2000/svg"
18+
class:list={["shrink-0", `h-${size}`, `text-${color}`, classes, isListMarker ? "mt-0.5" : ""]}
19+
fill="currentColor"
20+
stroke="none"
21+
viewBox="0 -2.5 32 24"
22+
style={`aspect-ratio: 32 / 24;`}
23+
aria-hidden={accessible ? "false" : "true"}
24+
focusable={focusable ? "true" : "false"}
25+
>
26+
{accessible && <title>Email - Solid Icon</title>}
27+
<path
28+
stroke="none"
29+
stroke-width="1.6"
30+
fill-rule="evenodd"
31+
d="M 16,17.4584 0,3.3384 V 21.5 H 32 V 3.3384 Z M 16.0016,13.1992 0,-0.9304 V -2.5 h 32 v 1.5696 z"
32+
></path>
33+
</svg>

src/components/Icon/icons/email.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const { color, classes, size, accessible, focusable, isListMarker, id } = Astro.
2222
aria-hidden={accessible ? "false" : "true"}
2323
focusable={focusable ? "true" : "false"}
2424
>
25-
{accessible && <title>email icon</title>}
25+
{accessible && <title>Email Icon</title>}
2626
<path
2727
stroke-linecap="round"
2828
stroke-linejoin="round"
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
export type Props = {
3+
color: string
4+
classes?: string
5+
size: number
6+
accessible: boolean
7+
focusable: boolean
8+
isListMarker?: boolean
9+
id?: string
10+
}
11+
12+
const { color, classes, size, accessible, focusable, isListMarker, id } = Astro.props
13+
---
14+
15+
<svg
16+
id={id}
17+
xmlns="http://www.w3.org/2000/svg"
18+
class:list={["shrink-0", `w-${size} h-${size}`, `text-${color}`, classes, isListMarker ? "mt-0.5" : ""]}
19+
fill="currentColor"
20+
stroke="none"
21+
viewBox="0 0 24 24"
22+
aria-hidden={accessible ? "false" : "true"}
23+
focusable={focusable ? "true" : "false"}
24+
>
25+
{accessible && <title>Print Icon</title>}
26+
<g transform="matrix(0.046875,0,0,0.046875,0,2.34375e-5)">
27+
<path
28+
d="m 105.037,367.926 v 0 l -0.24,0.001 v 80.383 c 0,8.592 6.967,15.556 15.559,15.556 h 271.289 c 8.592,0 15.559,-6.965 15.559,-15.556 V 367.927 H 106.275 Z"
29+
/>
30+
<rect
31+
x="136.203"
32+
y="108.761"
33+
width="239.17999"
34+
height="15.99"
35+
/>
36+
<polygon
37+
points="136.443,156.732 136.203,156.732 136.203,173.386 375.383,173.386 375.383,156.732 137.422,156.732 136.443,156.731 "
38+
/>
39+
<path
40+
d="M 431.846,207.957 V 48.134 H 81.836 l -1.442,-10e-4 v 10e-4 h -0.24 V 207.956 H 0 v 191.951 h 80.277 v -63.959 h 350.244 l 1.201,0.001 v 63.958 H 512 V 207.957 Z M 176,268.134 c 0,11.045 -8.953,20 -20,20 -11.047,0 -20,-8.955 -20,-20 0,-11.047 8.953,-20 20,-20 11.047,0 20,8.953 20,20 z m -64,0 c 0,11.045 -8.953,20 -20,20 -11.047,0 -20,-8.955 -20,-20 0,-11.047 8.953,-20 20,-20 11.047,0 20,8.953 20,20 z M 112.135,204.7 V 80.115 h 287.73 V 204.701 H 113.074 Z"
41+
/>
42+
</g>
43+
</svg>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
export type Props = {
3+
color: string
4+
classes?: string
5+
size: number
6+
accessible: boolean
7+
focusable: boolean
8+
isListMarker?: boolean
9+
id?: string
10+
}
11+
12+
const { color, classes, size, accessible, focusable, isListMarker, id } = Astro.props
13+
---
14+
15+
<svg
16+
id={id}
17+
xmlns="http://www.w3.org/2000/svg"
18+
class:list={["shrink-0", `w-${size + 5.422} h-${size}`, `text-${color}`, classes, isListMarker ? "mt-0.5" : ""]}
19+
fill="currentColor"
20+
stroke="none"
21+
viewBox="0 0 24 29.422"
22+
aria-hidden={accessible ? "false" : "true"}
23+
focusable={focusable ? "true" : "false"}
24+
>
25+
{accessible && <title>Telephone Icon</title>}
26+
<g
27+
transform="translate(0,2.2115455)"
28+
>
29+
<path
30+
d="M 12.000023,0 C 5.9560899,0 0,2.364755 0,5.0800881 c 0,2.331661 0,2.546911 0,2.5614431 0,0.6172512 0.50015724,1.1174079 1.1174085,1.1174079 h 4.2469771 c 0.6172512,0 1.1173615,-0.5001567 1.1173615,-1.1174079 V 5.7142141 c 0,-0.562501 0.4185946,-1.037439 0.9764082,-1.108455 0,0 1.5290189,-0.314063 4.5418677,-0.314063 3.01285,0 4.541822,0.314063 4.541822,0.314063 0.557861,0.070969 0.976408,0.545954 0.976408,1.108455 v 1.927363 c 0,0.6172518 0.500157,1.1174093 1.117362,1.1174093 h 4.246977 C 23.499843,8.7589864 24,8.2588289 24,7.6415771 24,7.6269988 24,7.4117491 24,5.0801351 24.000047,2.364755 18.044005,0 12.000023,0 Z"
31+
/>
32+
<path
33+
d="m 16.335924,7.6415771 v -1.870925 l -0.0322,-0.0067 c -0.01158,-0.0023 -1.47891,-0.289876 -4.303697,-0.289876 -2.8247863,0 -4.2920702,0.287532 -4.3066953,0.290532 l -0.029156,0.006 v 1.8709654 c 0,1.2683003 -1.0318145,2.299786 -2.2997857,2.299786 H 2.408911 v 6.6558875 c 0,1.645739 1.3339713,2.979662 2.9793809,2.979662 H 18.611756 c 1.645409,0 2.97938,-1.333971 2.97938,-2.979662 V 9.9413661 h -2.955475 c -1.26797,0 -2.299737,-1.0314857 -2.299737,-2.299786 z m -0.817597,7.4018119 v 1.590003 h -1.589675 v -1.590003 z m 0,-2.51438 v 1.59005 h -1.589675 v -1.59005 z m 0,-2.514005 v 1.589675 h -1.589675 v -1.589675 z m -2.723301,5.028385 v 1.590003 h -1.589675 v -1.590003 z m 0,-2.51438 v 1.59005 h -1.589675 v -1.59005 z m -1.589675,-0.92433 v -1.589675 h 1.589675 v 1.589675 z m -1.133628,3.43871 v 1.590003 H 8.4820481 v -1.590003 z m 0,-2.51438 v 1.59005 H 8.4820481 v -1.59005 z m 0,-2.514005 v 1.589675 H 8.4820481 v -1.589675 z"
34+
/>
35+
</g>
36+
</svg>

0 commit comments

Comments
 (0)