Skip to content
This repository was archived by the owner on Feb 27, 2024. It is now read-only.

Commit 2caaa40

Browse files
committed
Merge branch 'staging' into develop
2 parents 7596a0f + 1da1c38 commit 2caaa40

File tree

121 files changed

+3935
-1250
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

121 files changed

+3935
-1250
lines changed

.storybook/main.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
const path = require('path')
22

3-
// https://storybook.js.org/docs/react/configure/overview
3+
/**
4+
* Configure Storybook.
5+
*
6+
* @see https://storybook.js.org/docs/react/configure/overview
7+
*/
48
module.exports = {
59
reactOptions: {
610
fastRefresh: true,
711
strictMode: true
812
},
9-
stories: ['../components/**/**/*.stories.@(js|mdx)'],
13+
stories: [
14+
'../components/**/**/*.stories.@(js|mdx)',
15+
'../docs/**/**/*.stories.@(mdx)'
16+
],
1017
addons: [
1118
'@storybook/addon-a11y',
1219
'@storybook/addon-essentials',

.storybook/manager.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
import {addons} from '@storybook/addons'
22
import theme from './theme'
33

4+
/**
5+
* Configure Storybook features and behavior.
6+
*
7+
* @see https://storybook.js.org/docs/react/configure/features-and-behavior
8+
*/
49
addons.setConfig({
5-
theme
10+
isFullscreen: false,
11+
showNav: true,
12+
showPanel: true,
13+
panelPosition: 'bottom',
14+
sidebarAnimations: true,
15+
enableShortcuts: true,
16+
isToolshown: true,
17+
theme: theme,
18+
selectedPanel: undefined,
19+
initialActive: 'sidebar',
20+
showRoots: false
621
})

.storybook/preview-head.html

Lines changed: 0 additions & 11 deletions
This file was deleted.

.storybook/preview.js

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,60 @@
1-
import {withNextRouter} from 'storybook-addon-next-router'
1+
import {INITIAL_VIEWPORTS} from '@storybook/addon-viewport'
22
import {addDecorator} from '@storybook/react'
3-
3+
import {withNextRouter} from 'storybook-addon-next-router'
44
import '../styles/index.css'
55

6-
// This is so that we don't get "Uncaught TypeError: Cannot read property 'prefetch' of null" in stories with a Next.js link component.
6+
/**
7+
* Enable Next.js <Link /> component usage.
8+
*/
79
addDecorator(
810
withNextRouter({
911
path: '/'
1012
})
1113
)
1214

15+
/**
16+
* Custom viewports based on popular Apple devices.
17+
*/
1318
const customViewports = {
14-
mobile: {
15-
name: 'Mobile',
19+
largeMobile: {
20+
name: 'iPhone X/11/12 Pro',
1621
styles: {
17-
width: '375px',
18-
height: '667px'
19-
}
22+
width: '428px',
23+
height: '926px'
24+
},
25+
type: 'mobile'
2026
},
21-
tablet: {
22-
name: 'Tablet',
27+
smallLaptop: {
28+
name: 'MacBook Air 13"',
2329
styles: {
24-
width: '768px',
25-
height: '1024px'
30+
width: '1280px',
31+
height: '800px'
32+
},
33+
type: 'desktop'
34+
},
35+
largeLaptop: {
36+
name: 'MacBook Pro 16"',
37+
styles: {
38+
width: '1536px',
39+
height: '960px'
2640
}
41+
},
42+
destkop: {
43+
name: 'iMac 5k',
44+
styles: {
45+
width: '2048px',
46+
height: '1152px'
47+
},
48+
type: 'desktop'
2749
}
2850
}
2951

3052
export const parameters = {
3153
actions: {argTypesRegex: '^on[A-Z].*'},
3254
viewport: {
33-
viewports: customViewports
55+
viewports: {
56+
...customViewports,
57+
...INITIAL_VIEWPORTS
58+
}
3459
}
3560
}

.storybook/theme.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
import {create} from '@storybook/theming/create'
2-
import tailwindConfig from '../tailwind.config'
32

4-
export default create({})
3+
/**
4+
* Configure Storybook theme.
5+
*
6+
* @see https://storybook.js.org/docs/react/configure/theming#create-a-theme-quickstart
7+
*/
8+
export default create({
9+
base: 'light',
10+
brandTitle: 'WebDevStudios',
11+
brandUrl: 'https://webdevstudios.com'
12+
})
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import formatDefaultSeoData from '@/functions/formatDefaultSeoData'
2+
import {initializeWpApollo} from '../connector'
3+
import queryDefaultPageData from './queryDefaultPageData'
4+
import getMenus from '../menus/getMenus'
5+
6+
// Define SEO for Frontend routes.
7+
export const frontendPageSeo = {
8+
search: {
9+
title: 'Search',
10+
description: 'Search page'
11+
}
12+
}
13+
14+
/**
15+
* Retrieve data for Frontend-only route (i.e., page does not exist in WordPress).
16+
*
17+
* @author WebDevStudios
18+
* @param {string} route Frontend route.
19+
* @return {object} Object containing Apollo client instance and post data or error object.
20+
*/
21+
export default async function getFrontendPage(route) {
22+
// Get/create Apollo instance.
23+
const apolloClient = initializeWpApollo()
24+
25+
// Set up return object.
26+
const response = {
27+
apolloClient,
28+
error: false,
29+
errorMessage: null
30+
}
31+
32+
// Execute query.
33+
response.post = await apolloClient
34+
.query({query: queryDefaultPageData})
35+
.then((res) => {
36+
const {homepageSettings, siteSeo, menus} = res.data
37+
38+
// Retrieve menus.
39+
response.menus = getMenus(menus)
40+
41+
// Retrieve default SEO data.
42+
response.defaultSeo = formatDefaultSeoData({homepageSettings, siteSeo})
43+
44+
// Set route SEO.
45+
return {
46+
seo: {
47+
title: `${frontendPageSeo?.[route]?.title} - ${
48+
response.defaultSeo?.openGraph?.siteName ?? ''
49+
}`,
50+
metaDesc: frontendPageSeo?.[route]?.description,
51+
canonical: `${response.defaultSeo?.openGraph?.url ?? ''}/${route}`
52+
}
53+
}
54+
})
55+
.catch((error) => {
56+
response.error = true
57+
response.errorMessage = error.message
58+
59+
return null
60+
})
61+
62+
return response
63+
}

api/wordpress/_global/getPostTypeArchive.js

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,47 @@ import queryServicesArchive from '../services/queryServicesArchive'
77
import queryTeamsArchive from '../teams/queryTeamsArchive'
88
import queryPortfoliosArchive from '../portfolios/queryPortfoliosArchive'
99
import queryTestimonialsArchive from '../testimonials/queryTestimonialsArchive'
10+
import formatDefaultSeoData from '@/functions/formatDefaultSeoData'
11+
import getMenus from '../menus/getMenus'
12+
13+
// Define SEO for archives.
14+
export const archiveSeo = {
15+
career: {
16+
title: 'Careers',
17+
description: '',
18+
route: 'careers'
19+
},
20+
event: {
21+
title: 'Events',
22+
description: '',
23+
route: 'events'
24+
},
25+
portfolio: {
26+
title: 'Portfolio',
27+
description: '',
28+
route: 'portfolio'
29+
},
30+
post: {
31+
title: 'Blog',
32+
description: '',
33+
route: 'blog'
34+
},
35+
service: {
36+
title: 'Services',
37+
description: '',
38+
route: 'service'
39+
},
40+
team: {
41+
title: 'Team Members',
42+
description: '',
43+
route: 'team'
44+
},
45+
testimonial: {
46+
title: 'Testimonials',
47+
description: '',
48+
route: 'testimonial'
49+
}
50+
}
1051

1152
/**
1253
* Retrieve post archive.
@@ -77,8 +118,16 @@ export default async function getPostTypeArchive(
77118
await apolloClient
78119
.query({query, variables})
79120
.then((archive) => {
121+
const {homepageSettings, siteSeo, menus, ...archiveData} = archive.data
122+
123+
// Retrieve menus.
124+
response.menus = getMenus(menus)
125+
126+
// Retrieve default SEO data.
127+
response.defaultSeo = formatDefaultSeoData({homepageSettings, siteSeo})
128+
80129
const pluralType = postTypes[postType] ?? postType
81-
const data = archive?.data?.[pluralType] ?? null
130+
const data = archiveData?.[pluralType] ?? null
82131

83132
// Set error props if data not found.
84133
if (!data?.edges || !data?.pageInfo) {
@@ -91,6 +140,29 @@ export default async function getPostTypeArchive(
91140
// Flatten posts array to include inner node post data.
92141
response.posts = data.edges.map((post) => post.node)
93142

143+
// Attempt to use posts page for blog, default to custom SEO.
144+
response.post = {
145+
seo:
146+
'post' === postType && homepageSettings?.postsPage?.seo
147+
? {
148+
...homepageSettings.postsPage.seo,
149+
canonical: `${response.defaultSeo?.openGraph?.url ?? ''}/${
150+
archiveSeo?.[postType]?.route
151+
}`
152+
}
153+
: {
154+
title: `${archiveSeo?.[postType]?.title} - ${
155+
response.defaultSeo?.openGraph?.siteName ?? ''
156+
}`,
157+
metaDesc: archiveSeo?.[postType]?.description,
158+
canonical: `${response.defaultSeo?.openGraph?.url ?? ''}/${
159+
archiveSeo?.[postType]?.route
160+
}`,
161+
metaRobotsNofollow: 'follow',
162+
metaRobotsNoindex: 'index'
163+
}
164+
}
165+
94166
// Extract pagination data.
95167
response.pagination = data.pageInfo
96168
})

api/wordpress/_global/getPostTypeById.js

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import queryServiceById from '../services/queryServiceById'
99
import queryTeamById from '../teams/queryTeamById'
1010
import queryPortfolioById from '../portfolios/queryPortfolioById'
1111
import queryTestimonialById from '../testimonials/queryTestimonialById'
12+
import formatDefaultSeoData from '@/functions/formatDefaultSeoData'
13+
import getMenus from '../menus/getMenus'
1214

1315
/**
1416
* Retrieve single post by specified identifier.
@@ -63,29 +65,45 @@ export default async function getPostTypeById(postType, id, idType = 'SLUG') {
6365
// Execute query.
6466
response.post = await apolloClient
6567
.query({query, variables: {id, idType}})
66-
.then((post) => {
68+
.then((res) => {
69+
const {homepageSettings, siteSeo, menus, ...postData} = res.data
70+
71+
// Retrieve menus.
72+
response.menus = getMenus(menus)
73+
74+
// Retrieve default SEO data.
75+
response.defaultSeo = formatDefaultSeoData({homepageSettings, siteSeo})
76+
77+
const post = postData?.[postType]
78+
6779
// Set error props if data not found.
68-
if (!post?.data?.[postType]) {
80+
if (!post) {
6981
response.error = true
7082
response.errorMessage = `An error occurred while trying to retrieve data for ${postType} "${id}."`
7183

7284
return null
7385
}
7486

75-
return post.data[postType]
87+
return post
7688
})
7789
.then(async (post) => {
90+
// Add slug/ID to post.
91+
const newPost = {
92+
...post,
93+
slug: id
94+
}
95+
7896
// Handle blocks.
7997
if (!post || !post?.blocksJSON) {
8098
return post
8199
}
82100

83-
const newPost = {...post}
84-
85101
newPost.blocks = await formatBlockData(
86102
JSON.parse(newPost.blocksJSON) ?? []
87103
)
88104

105+
delete newPost.blocksJSON
106+
89107
return newPost
90108
})
91109
.catch((error) => {

0 commit comments

Comments
 (0)