Skip to content

Commit

Permalink
Merge pull request #265 from dgattey/dgattey/projects
Browse files Browse the repository at this point in the history
feat: fetch real project data + add thumbnails on home page
  • Loading branch information
Dylan Gattey committed Jan 14, 2022
2 parents 68f74bb + df78659 commit bf124ef
Show file tree
Hide file tree
Showing 16 changed files with 380 additions and 69 deletions.
3 changes: 3 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ const nextConfig = {
// Enables the styled-components SWC transform
styledComponents: true,
},
images: {
domains: ['images.ctfassets.net'],
},
};

module.exports = nextConfig;
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"next": "12.0.7",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-icons": "4.3.1",
"react-is": "17.0.2",
"styled-components": "5.3.3",
"swr": "1.1.2-beta.0"
Expand Down
45 changes: 45 additions & 0 deletions src/api/contentful/fetchProjects.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { gql } from 'graphql-request';
import fetchGraphQLData from '../fetchGraphQLData';
import { Project } from './generated/api.generated';
import { ProjectsQuery } from './generated/fetchProjects.generated';
import { isProject } from './typeguards';

type Projects = Array<Project>;

/**
* Grabs all projects to display
*/
const QUERY = gql`
query Projects {
projectCollection(order: creationDate_DESC) {
items {
title
creationDate
type
link {
url
}
layout
thumbnail {
url
width
height
}
description {
json
}
}
}
}
`;

/**
* Fetches the section corresponding to the projects and finds the nodes within it
* to transform into Projects
*/
const fetchProjects = async (): Promise<Projects> => {
const data = await fetchGraphQLData<ProjectsQuery>('/api/content', QUERY);
return data?.projectCollection?.items.filter(isProject) ?? [];
};

export default fetchProjects;
73 changes: 49 additions & 24 deletions src/api/contentful/generated/api.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,18 @@ export type AssetFilter = {
};

export type AssetLinkingCollections = {
readonly bookCollection: Maybe<BookCollection>;
readonly entryCollection: Maybe<EntryCollection>;
readonly projectCollection: Maybe<ProjectCollection>;
};

export type AssetLinkingCollectionsBookCollectionArgs = {
limit?: InputMaybe<Scalars['Int']>;
locale: InputMaybe<Scalars['String']>;
preview: InputMaybe<Scalars['Boolean']>;
skip?: InputMaybe<Scalars['Int']>;
};

export type AssetLinkingCollectionsEntryCollectionArgs = {
limit?: InputMaybe<Scalars['Int']>;
locale: InputMaybe<Scalars['String']>;
Expand Down Expand Up @@ -173,9 +181,10 @@ export type AssetOrder =
export type Book = Entry & {
readonly author: Maybe<Scalars['String']>;
readonly contentfulMetadata: ContentfulMetadata;
readonly coverImageUrl: Maybe<Scalars['String']>;
readonly coverImage: Maybe<Asset>;
readonly description: Maybe<BookDescription>;
readonly linkedFrom: Maybe<BookLinkingCollections>;
readonly readDate: Maybe<Scalars['DateTime']>;
readonly sys: Sys;
readonly title: Maybe<Scalars['String']>;
};
Expand All @@ -186,8 +195,9 @@ export type BookAuthorArgs = {
};

/** All data describing a recent book I've read. [See type definition](https://app.contentful.com/spaces/nb3rzo39eupw/content_types/book) */
export type BookCoverImageUrlArgs = {
export type BookCoverImageArgs = {
locale: InputMaybe<Scalars['String']>;
preview: InputMaybe<Scalars['Boolean']>;
};

/** All data describing a recent book I've read. [See type definition](https://app.contentful.com/spaces/nb3rzo39eupw/content_types/book) */
Expand All @@ -200,6 +210,11 @@ export type BookLinkedFromArgs = {
allowedLocales: InputMaybe<ReadonlyArray<InputMaybe<Scalars['String']>>>;
};

/** All data describing a recent book I've read. [See type definition](https://app.contentful.com/spaces/nb3rzo39eupw/content_types/book) */
export type BookReadDateArgs = {
locale: InputMaybe<Scalars['String']>;
};

/** All data describing a recent book I've read. [See type definition](https://app.contentful.com/spaces/nb3rzo39eupw/content_types/book) */
export type BookTitleArgs = {
locale: InputMaybe<Scalars['String']>;
Expand Down Expand Up @@ -244,16 +259,19 @@ export type BookFilter = {
readonly author_not_contains: InputMaybe<Scalars['String']>;
readonly author_not_in: InputMaybe<ReadonlyArray<InputMaybe<Scalars['String']>>>;
readonly contentfulMetadata: InputMaybe<ContentfulMetadataFilter>;
readonly coverImageUrl: InputMaybe<Scalars['String']>;
readonly coverImageUrl_contains: InputMaybe<Scalars['String']>;
readonly coverImageUrl_exists: InputMaybe<Scalars['Boolean']>;
readonly coverImageUrl_in: InputMaybe<ReadonlyArray<InputMaybe<Scalars['String']>>>;
readonly coverImageUrl_not: InputMaybe<Scalars['String']>;
readonly coverImageUrl_not_contains: InputMaybe<Scalars['String']>;
readonly coverImageUrl_not_in: InputMaybe<ReadonlyArray<InputMaybe<Scalars['String']>>>;
readonly coverImage_exists: InputMaybe<Scalars['Boolean']>;
readonly description_contains: InputMaybe<Scalars['String']>;
readonly description_exists: InputMaybe<Scalars['Boolean']>;
readonly description_not_contains: InputMaybe<Scalars['String']>;
readonly readDate: InputMaybe<Scalars['DateTime']>;
readonly readDate_exists: InputMaybe<Scalars['Boolean']>;
readonly readDate_gt: InputMaybe<Scalars['DateTime']>;
readonly readDate_gte: InputMaybe<Scalars['DateTime']>;
readonly readDate_in: InputMaybe<ReadonlyArray<InputMaybe<Scalars['DateTime']>>>;
readonly readDate_lt: InputMaybe<Scalars['DateTime']>;
readonly readDate_lte: InputMaybe<Scalars['DateTime']>;
readonly readDate_not: InputMaybe<Scalars['DateTime']>;
readonly readDate_not_in: InputMaybe<ReadonlyArray<InputMaybe<Scalars['DateTime']>>>;
readonly sys: InputMaybe<SysFilter>;
readonly title: InputMaybe<Scalars['String']>;
readonly title_contains: InputMaybe<Scalars['String']>;
Expand Down Expand Up @@ -286,8 +304,8 @@ export type BookLinkingCollectionsSectionCollectionArgs = {
export type BookOrder =
| 'author_ASC'
| 'author_DESC'
| 'coverImageUrl_ASC'
| 'coverImageUrl_DESC'
| 'readDate_ASC'
| 'readDate_DESC'
| 'sys_firstPublishedAt_ASC'
| 'sys_firstPublishedAt_DESC'
| 'sys_id_ASC'
Expand Down Expand Up @@ -555,6 +573,7 @@ export type Project = Entry & {
readonly contentfulMetadata: ContentfulMetadata;
readonly creationDate: Maybe<Scalars['DateTime']>;
readonly description: Maybe<ProjectDescription>;
readonly layout: Maybe<Scalars['String']>;
readonly link: Maybe<Link>;
readonly linkedFrom: Maybe<ProjectLinkingCollections>;
readonly sys: Sys;
Expand All @@ -573,6 +592,11 @@ export type ProjectDescriptionArgs = {
locale: InputMaybe<Scalars['String']>;
};

/** Website, app, other code-based project, or graphics created for something. [See type definition](https://app.contentful.com/spaces/nb3rzo39eupw/content_types/project) */
export type ProjectLayoutArgs = {
locale: InputMaybe<Scalars['String']>;
};

/** Website, app, other code-based project, or graphics created for something. [See type definition](https://app.contentful.com/spaces/nb3rzo39eupw/content_types/project) */
export type ProjectLinkArgs = {
locale: InputMaybe<Scalars['String']>;
Expand Down Expand Up @@ -644,6 +668,13 @@ export type ProjectFilter = {
readonly description_contains: InputMaybe<Scalars['String']>;
readonly description_exists: InputMaybe<Scalars['Boolean']>;
readonly description_not_contains: InputMaybe<Scalars['String']>;
readonly layout: InputMaybe<Scalars['String']>;
readonly layout_contains: InputMaybe<Scalars['String']>;
readonly layout_exists: InputMaybe<Scalars['Boolean']>;
readonly layout_in: InputMaybe<ReadonlyArray<InputMaybe<Scalars['String']>>>;
readonly layout_not: InputMaybe<Scalars['String']>;
readonly layout_not_contains: InputMaybe<Scalars['String']>;
readonly layout_not_in: InputMaybe<ReadonlyArray<InputMaybe<Scalars['String']>>>;
readonly link: InputMaybe<CfLinkNestedFilter>;
readonly link_exists: InputMaybe<Scalars['Boolean']>;
readonly sys: InputMaybe<SysFilter>;
Expand Down Expand Up @@ -683,6 +714,8 @@ export type ProjectLinkingCollectionsSectionCollectionArgs = {
export type ProjectOrder =
| 'creationDate_ASC'
| 'creationDate_DESC'
| 'layout_ASC'
| 'layout_DESC'
| 'sys_firstPublishedAt_ASC'
| 'sys_firstPublishedAt_DESC'
| 'sys_id_ASC'
Expand Down Expand Up @@ -792,7 +825,7 @@ export type QuerySectionCollectionArgs = {
where: InputMaybe<SectionFilter>;
};

/** A section containing references to other blocks. Based on the content of the section, may appear differently on different pages. [See type definition](https://app.contentful.com/spaces/nb3rzo39eupw/content_types/section) */
/** A collection of references to other nodes [See type definition](https://app.contentful.com/spaces/nb3rzo39eupw/content_types/section) */
export type Section = Entry & {
readonly blocksCollection: Maybe<SectionBlocksCollection>;
readonly contentfulMetadata: ContentfulMetadata;
Expand All @@ -801,20 +834,20 @@ export type Section = Entry & {
readonly title: Maybe<Scalars['String']>;
};

/** A section containing references to other blocks. Based on the content of the section, may appear differently on different pages. [See type definition](https://app.contentful.com/spaces/nb3rzo39eupw/content_types/section) */
/** A collection of references to other nodes [See type definition](https://app.contentful.com/spaces/nb3rzo39eupw/content_types/section) */
export type SectionBlocksCollectionArgs = {
limit?: InputMaybe<Scalars['Int']>;
locale: InputMaybe<Scalars['String']>;
preview: InputMaybe<Scalars['Boolean']>;
skip?: InputMaybe<Scalars['Int']>;
};

/** A section containing references to other blocks. Based on the content of the section, may appear differently on different pages. [See type definition](https://app.contentful.com/spaces/nb3rzo39eupw/content_types/section) */
/** A collection of references to other nodes [See type definition](https://app.contentful.com/spaces/nb3rzo39eupw/content_types/section) */
export type SectionLinkedFromArgs = {
allowedLocales: InputMaybe<ReadonlyArray<InputMaybe<Scalars['String']>>>;
};

/** A section containing references to other blocks. Based on the content of the section, may appear differently on different pages. [See type definition](https://app.contentful.com/spaces/nb3rzo39eupw/content_types/section) */
/** A collection of references to other nodes [See type definition](https://app.contentful.com/spaces/nb3rzo39eupw/content_types/section) */
export type SectionTitleArgs = {
locale: InputMaybe<Scalars['String']>;
};
Expand All @@ -826,7 +859,7 @@ export type SectionBlocksCollection = {
readonly total: Scalars['Int'];
};

export type SectionBlocksItem = Book | Link | Project | Section;
export type SectionBlocksItem = Book | Link | Project;

export type SectionCollection = {
readonly items: ReadonlyArray<Maybe<Section>>;
Expand All @@ -852,7 +885,6 @@ export type SectionFilter = {

export type SectionLinkingCollections = {
readonly entryCollection: Maybe<EntryCollection>;
readonly sectionCollection: Maybe<SectionCollection>;
};

export type SectionLinkingCollectionsEntryCollectionArgs = {
Expand All @@ -862,13 +894,6 @@ export type SectionLinkingCollectionsEntryCollectionArgs = {
skip?: InputMaybe<Scalars['Int']>;
};

export type SectionLinkingCollectionsSectionCollectionArgs = {
limit?: InputMaybe<Scalars['Int']>;
locale: InputMaybe<Scalars['String']>;
preview: InputMaybe<Scalars['Boolean']>;
skip?: InputMaybe<Scalars['Int']>;
};

export type SectionOrder =
| 'sys_firstPublishedAt_ASC'
| 'sys_firstPublishedAt_DESC'
Expand Down
28 changes: 28 additions & 0 deletions src/api/contentful/generated/fetchProjects.generated.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type * as Types from './api.generated';

export type ProjectsQueryVariables = Types.Exact<{ [key: string]: never }>;

export type ProjectsQuery = {
readonly projectCollection:
| {
readonly items: ReadonlyArray<
| {
readonly title: string | undefined;
readonly creationDate: any | undefined;
readonly type: ReadonlyArray<string | undefined> | undefined;
readonly layout: string | undefined;
readonly link: { readonly url: string | undefined } | undefined;
readonly thumbnail:
| {
readonly url: string | undefined;
readonly width: number | undefined;
readonly height: number | undefined;
}
| undefined;
readonly description: { readonly json: any } | undefined;
}
| undefined
>;
}
| undefined;
};
15 changes: 0 additions & 15 deletions src/api/contentful/generated/fetchSiteFooter.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,6 @@ export type SiteFooterQuery = {
readonly url: string | undefined;
readonly icon: string | undefined;
}
| {
readonly blocksCollection:
| {
readonly items: ReadonlyArray<
| {
readonly title: string | undefined;
readonly url: string | undefined;
readonly icon: string | undefined;
}
| {}
| undefined
>;
}
| undefined;
}
| {}
| undefined
>;
Expand Down
9 changes: 8 additions & 1 deletion src/api/contentful/typeguards.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Link } from './generated/api.generated';
import type { Link, Project } from './generated/api.generated';

/**
* Type guard to get a link out
Expand All @@ -7,6 +7,13 @@ export const isLink = (item: Link | undefined | Record<string, unknown>): item i
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
!!(item as Link)?.title;

/**
* Type guard to get a project out
*/
export const isProject = (item: Project | undefined | Record<string, unknown>): item is Project =>
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
!!(item as Project)?.creationDate && !!(item as Project)?.thumbnail;

/**
* Type guard to filter out null or undefined items
*/
Expand Down
6 changes: 6 additions & 0 deletions src/api/useData.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import useSWR from 'swr';
import fetchProjects from './contentful/fetchProjects';
import fetchSiteFooter from './contentful/fetchSiteFooter';
import fetchSiteHeader from './contentful/fetchSiteHeader';
import fetchRepoVersion from './github/fetchRepoVersion';
Expand Down Expand Up @@ -40,6 +41,11 @@ const fetchers = {
* Text links for the full site header
*/
siteHeader: fetchSiteHeader,

/**
* All projects to list on home page
*/
projects: fetchProjects,
} as const;

/**
Expand Down
Loading

1 comment on commit bf124ef

@vercel
Copy link

@vercel vercel bot commented on bf124ef Jan 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

Please sign in to comment.