From 31214cf2be7f5f0c8387052c06cf13e6adf833e8 Mon Sep 17 00:00:00 2001 From: Shubh Sharma <69891912+shubhsharma19@users.noreply.github.com> Date: Wed, 18 Oct 2023 14:55:31 +0530 Subject: [PATCH 001/163] Update README.md --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 593a5cffe..a42c9b1ac 100644 --- a/README.md +++ b/README.md @@ -32,14 +32,14 @@ Blog Starter Kit lets you instantly deploy a Next.js and Tailwind powered fronte ### Step 1 -The recommended approach is depoying to Vercel. If you don't have an account already, sign up for a free plan. +The recommended approach is deploying to Vercel. If you don't have an account already, you can sign up for a free plan. - Fork this repo - Create a new project on Vercel and connect this repo -- It's a monorepo. So, choose the either `packages/blog-starter-kit/themes/enterprise` or `packages/blog-starter-kit/themes/personal` as the root directory while importing on Vercel. - ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1695083263935/T5bByLxZT.png?w=500&h=800&auto=format) +- It's a monorepo. So, choose either `packages/blog-starter-kit/themes/enterprise` or `packages/blog-starter-kit/themes/personal` as the root directory while importing on Vercel. + ![selecting the directory to deploy a monorepo](https://cdn.hashnode.com/res/hashnode/image/upload/v1695083263935/T5bByLxZT.png?w=500&h=800&auto=format) - Choose `Next.js` as framework preset (just above Root Directory setting). -- Set the following env vars +- Set the following environment variables ``` NEXT_PUBLIC_HASHNODE_GQL_ENDPOINT=https://gql.hashnode.com @@ -113,7 +113,7 @@ async function proxyBlog(request) { } ``` -Be sure to replace the values of `subpath` and `blogBaseUrl` in the above snippet. This way cloudflare will proxy all the requests starting with `youdomain.com/blog` to your headless blog, and other requests will hit your origin as usual. +Be sure to replace the values of `subpath` and `blogBaseUrl` in the above code snippet. This way cloudflare will proxy all the requests starting with `youdomain.com/blog` to your headless blog, and other requests will hit your origin as usual. If your main domain is hosted elsewhere, you need to involve engineers from your team to create above rewrites. @@ -121,11 +121,11 @@ If your main domain is hosted elsewhere, you need to involve engineers from your Now that you have deployed the starter kit on your own domain, you need to tell Hashnode not to generate a UI for your blog. You can do that by visiting your blog dashboard -> advanced tab. Scroll down and locate the section "use Hashnode as a headless CMS". Enable it and enter your blog base URL. -![](https://cdn.hashnode.com/res/hashnode/image/upload/v1697486863293/zMMctLjRZ.png?auto=format) +![enable headless mode](https://cdn.hashnode.com/res/hashnode/image/upload/v1697486863293/zMMctLjRZ.png?auto=format) After enabling, enter your blog URL like the following and save. -![](https://cdn.hashnode.com/res/hashnode/image/upload/v1697487035077/1sIyw_0v1.png?auto=format) +![blog base url](https://cdn.hashnode.com/res/hashnode/image/upload/v1697487035077/1sIyw_0v1.png?auto=format) Congrats 🎉! Hashnode will now treat your blog as a headless blog and send readers directly to the origin. From 579bc32cbf5a0302e081e36d4b3fc6d6098db4b2 Mon Sep 17 00:00:00 2001 From: Ayodele Samuel Adebayo Date: Sat, 21 Oct 2023 23:26:49 +0100 Subject: [PATCH 002/163] Add post read time in minute to post header and display author, date and read time on mobile --- .../enterprise/components/date-formatter.tsx | 7 +++- .../components/icons/svgs/BookOpenSVG.js | 11 ++++++ .../enterprise/components/post-header.tsx | 11 ++++-- .../components/post-read-time-in-minutes.tsx | 15 ++++++++ .../themes/enterprise/generated/graphql.ts | 37 +++++++------------ .../enterprise/generated/schema.graphql | 24 ++++++------ .../themes/enterprise/pages/[slug].tsx | 8 +++- 7 files changed, 71 insertions(+), 42 deletions(-) create mode 100644 packages/blog-starter-kit/themes/enterprise/components/icons/svgs/BookOpenSVG.js create mode 100644 packages/blog-starter-kit/themes/enterprise/components/post-read-time-in-minutes.tsx diff --git a/packages/blog-starter-kit/themes/enterprise/components/date-formatter.tsx b/packages/blog-starter-kit/themes/enterprise/components/date-formatter.tsx index 00129ab31..000b76640 100644 --- a/packages/blog-starter-kit/themes/enterprise/components/date-formatter.tsx +++ b/packages/blog-starter-kit/themes/enterprise/components/date-formatter.tsx @@ -8,5 +8,10 @@ export const DateFormatter = ({ dateString }: Props) => { if (!dateString) return <>; const date = parseISO(dateString); - return ; + return ( + <> + · + + + ); }; diff --git a/packages/blog-starter-kit/themes/enterprise/components/icons/svgs/BookOpenSVG.js b/packages/blog-starter-kit/themes/enterprise/components/icons/svgs/BookOpenSVG.js new file mode 100644 index 000000000..6fb9be0fd --- /dev/null +++ b/packages/blog-starter-kit/themes/enterprise/components/icons/svgs/BookOpenSVG.js @@ -0,0 +1,11 @@ +import React from 'react'; + +export default class BookOpenSVG extends React.Component { + render() { + return ( + + + + ); + } +} diff --git a/packages/blog-starter-kit/themes/enterprise/components/post-header.tsx b/packages/blog-starter-kit/themes/enterprise/components/post-header.tsx index 1f7ab2560..5daed7f36 100644 --- a/packages/blog-starter-kit/themes/enterprise/components/post-header.tsx +++ b/packages/blog-starter-kit/themes/enterprise/components/post-header.tsx @@ -3,6 +3,7 @@ import { User } from '../generated/graphql'; import { Avatar } from './avatar'; import { CoverImage } from './cover-image'; import { DateFormatter } from './date-formatter'; +import { ReadTimeInMinutes } from './post-read-time-in-minutes'; import { PostTitle } from './post-title'; type Author = Pick; @@ -12,20 +13,24 @@ type Props = { coverImage: string | null | undefined; date: string; author: Author; + readTimeInMinutes: number; }; -export const PostHeader = ({ title, coverImage, date, author }: Props) => { +export const PostHeader = ({ title, coverImage, date, author, readTimeInMinutes }: Props) => { return ( <> {title} -
+
- +
+ + +
{coverImage && (
diff --git a/packages/blog-starter-kit/themes/enterprise/components/post-read-time-in-minutes.tsx b/packages/blog-starter-kit/themes/enterprise/components/post-read-time-in-minutes.tsx new file mode 100644 index 000000000..f7cca1ef2 --- /dev/null +++ b/packages/blog-starter-kit/themes/enterprise/components/post-read-time-in-minutes.tsx @@ -0,0 +1,15 @@ +import BookOpenSVG from './icons/svgs/BookOpenSVG'; + +type Props = { readTimeInMinutes: number }; + +export const ReadTimeInMinutes = ({ readTimeInMinutes }: Props) => { + return ( + <> + · +

+ + {readTimeInMinutes} min read +

+ + ); +}; diff --git a/packages/blog-starter-kit/themes/enterprise/generated/graphql.ts b/packages/blog-starter-kit/themes/enterprise/generated/graphql.ts index 5a9b45942..0618cb15a 100644 --- a/packages/blog-starter-kit/themes/enterprise/generated/graphql.ts +++ b/packages/blog-starter-kit/themes/enterprise/generated/graphql.ts @@ -442,6 +442,8 @@ export enum FeedType { * Personalised feed is curated per requesting user basis. */ Personalized = 'PERSONALIZED', + /** Returns posts which were viewed by the user, sorted based on recency. */ + ReadingHistory = 'READING_HISTORY', /** Returns posts which were published recently, sorted based on recency. */ Recent = 'RECENT', /** Returns posts based on old personalization algorithm. */ @@ -486,18 +488,13 @@ export type IUser = { availableFor?: Maybe; /** Returns a list of badges that the user has earned. Shown on blogs /badges page. Example - https://iamshadmirza.com/badges */ badges: Array; + /** The bio of the user. Visible in about me section of the user's profile. */ + bio?: Maybe; /** * The bio of the user. Visible in about me section of the user's profile. - * @deprecated Will be removed on 18/09/2023. Use bioV2 instead of bio. + * @deprecated Will be removed on 26/10/2023. Use bio instead of bioV2 */ - bio?: Maybe; - /** The bio of the user. Visible in about me section of the user's profile. */ bioV2?: Maybe; - /** - * The URL to the cover photo of the user's profile. - * @deprecated Cover images are not part of user's profile anymore. Will be removed on 25/09/2023. - */ - coverPhoto?: Maybe; /** The date the user joined Hashnode. */ dateJoined?: Maybe; /** Whether or not the user is deactivated. */ @@ -611,18 +608,13 @@ export type MyUser = IUser & Node & { badges: Array; /** A list of beta features that the user has access to. Only available to the authenticated user. */ betaFeatures: Array; + /** The bio of the user. Visible in about me section of the user's profile. */ + bio?: Maybe; /** * The bio of the user. Visible in about me section of the user's profile. - * @deprecated Will be removed on 18/09/2023. Use bioV2 instead of bio. + * @deprecated Will be removed on 26/10/2023. Use bio instead of bio.V2 */ - bio?: Maybe; - /** The bio of the user. Visible in about me section of the user's profile. */ bioV2?: Maybe; - /** - * The URL to the cover photo of the user's profile. - * @deprecated Cover images are not part of user's profile anymore. Will be removed on 25/09/2023. - */ - coverPhoto?: Maybe; /** The date the user joined Hashnode. */ dateJoined?: Maybe; /** Whether or not the user is deactivated. */ @@ -1056,6 +1048,8 @@ export type Preferences = { disableFooterBranding?: Maybe; /** An object containing pages enabled for the publication. */ enabledPages?: Maybe; + /** A flag indicating if subscription popup needs to be shown to be shown for the publication */ + isSubscriptionModalDisabled?: Maybe; /** The selected publication's layout, can be stacked, grid or magazine. */ layout?: Maybe; /** The publication's logo url. */ @@ -2002,18 +1996,13 @@ export type User = IUser & Node & { availableFor?: Maybe; /** Returns a list of badges that the user has earned. Shown on blogs /badges page. Example - https://iamshadmirza.com/badges */ badges: Array; + /** The bio of the user. Visible in about me section of the user's profile. */ + bio?: Maybe; /** * The bio of the user. Visible in about me section of the user's profile. - * @deprecated Will be removed on 18/09/2023. Use bioV2 instead of bio. + * @deprecated Will be removed on 26/10/2023. Use bio instead of bioV2 */ - bio?: Maybe; - /** The bio of the user. Visible in about me section of the user's profile. */ bioV2?: Maybe; - /** - * The URL to the cover photo of the user's profile. - * @deprecated Cover images are not part of user's profile anymore. Will be removed on 25/09/2023. - */ - coverPhoto?: Maybe; /** The date the user joined Hashnode. */ dateJoined?: Maybe; /** Whether or not the user is deactivated. */ diff --git a/packages/blog-starter-kit/themes/enterprise/generated/schema.graphql b/packages/blog-starter-kit/themes/enterprise/generated/schema.graphql index 7c5f399ab..ca2ed5f00 100644 --- a/packages/blog-starter-kit/themes/enterprise/generated/schema.graphql +++ b/packages/blog-starter-kit/themes/enterprise/generated/schema.graphql @@ -447,6 +447,8 @@ enum FeedType { Personalised feed is curated per requesting user basis. """ PERSONALIZED + """Returns posts which were viewed by the user, sorted based on recency.""" + READING_HISTORY """Returns posts which were published recently, sorted based on recency.""" RECENT """Returns posts based on old personalization algorithm.""" @@ -502,13 +504,11 @@ interface IUser { """ The bio of the user. Visible in about me section of the user's profile. """ - bio: String @deprecated(reason: "Will be removed on 18/09/2023. Use bioV2 instead of bio.") + bio: Content """ The bio of the user. Visible in about me section of the user's profile. """ - bioV2: Content - """The URL to the cover photo of the user's profile.""" - coverPhoto: String @deprecated(reason: "Cover images are not part of user's profile anymore. Will be removed on 25/09/2023.") + bioV2: Content @deprecated(reason: "Will be removed on 26/10/2023. Use bio instead of bioV2") """The date the user joined Hashnode.""" dateJoined: DateTime """Whether or not the user is deactivated.""" @@ -607,13 +607,11 @@ type MyUser implements IUser & Node { """ The bio of the user. Visible in about me section of the user's profile. """ - bio: String @deprecated(reason: "Will be removed on 18/09/2023. Use bioV2 instead of bio.") + bio: Content """ The bio of the user. Visible in about me section of the user's profile. """ - bioV2: Content - """The URL to the cover photo of the user's profile.""" - coverPhoto: String @deprecated(reason: "Cover images are not part of user's profile anymore. Will be removed on 25/09/2023.") + bioV2: Content @deprecated(reason: "Will be removed on 26/10/2023. Use bio instead of bio.V2") """The date the user joined Hashnode.""" dateJoined: DateTime """Whether or not the user is deactivated.""" @@ -1086,6 +1084,10 @@ type Preferences { disableFooterBranding: Boolean """An object containing pages enabled for the publication.""" enabledPages: PagesPreferences + """ + A flag indicating if subscription popup needs to be shown to be shown for the publication + """ + isSubscriptionModalDisabled: Boolean """The selected publication's layout, can be stacked, grid or magazine.""" layout: PublicationLayout """The publication's logo url.""" @@ -2013,13 +2015,11 @@ type User implements IUser & Node { """ The bio of the user. Visible in about me section of the user's profile. """ - bio: String @deprecated(reason: "Will be removed on 18/09/2023. Use bioV2 instead of bio.") + bio: Content """ The bio of the user. Visible in about me section of the user's profile. """ - bioV2: Content - """The URL to the cover photo of the user's profile.""" - coverPhoto: String @deprecated(reason: "Cover images are not part of user's profile anymore. Will be removed on 25/09/2023.") + bioV2: Content @deprecated(reason: "Will be removed on 26/10/2023. Use bio instead of bioV2") """The date the user joined Hashnode.""" dateJoined: DateTime """Whether or not the user is deactivated.""" diff --git a/packages/blog-starter-kit/themes/enterprise/pages/[slug].tsx b/packages/blog-starter-kit/themes/enterprise/pages/[slug].tsx index 85dac058f..5c0e6d019 100644 --- a/packages/blog-starter-kit/themes/enterprise/pages/[slug].tsx +++ b/packages/blog-starter-kit/themes/enterprise/pages/[slug].tsx @@ -67,9 +67,12 @@ const Post = (publication: PublicationFragment, post: PostFullFragment) => { {post.seo?.title || post.title} - + - + { coverImage={post.coverImage?.url} date={post.publishedAt} author={post.author} + readTimeInMinutes={post.readTimeInMinutes} /> {post.features.tableOfContents.isEnabled && } From 4a351063b59cc7e9e300984eda5338204f40dd04 Mon Sep 17 00:00:00 2001 From: Ayodele Samuel Adebayo Date: Sat, 21 Oct 2023 23:35:09 +0100 Subject: [PATCH 003/163] Add readTimeInMinutes prop to PostHeader in Pages preview [id] page --- .../blog-starter-kit/themes/enterprise/pages/preview/[id].tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/blog-starter-kit/themes/enterprise/pages/preview/[id].tsx b/packages/blog-starter-kit/themes/enterprise/pages/preview/[id].tsx index a38eb980b..be04dd996 100644 --- a/packages/blog-starter-kit/themes/enterprise/pages/preview/[id].tsx +++ b/packages/blog-starter-kit/themes/enterprise/pages/preview/[id].tsx @@ -60,6 +60,7 @@ export default function Post({ publication, post }: Props) { coverImage={post.coverImage?.url} date={post.publishedAt} author={post.author} + readTimeInMinutes={post.readTimeInMinutes} />
From b07dbb1106de52089d83fe6a11724ff224e8fc2c Mon Sep 17 00:00:00 2001 From: Ayodele Samuel Adebayo Date: Sun, 22 Oct 2023 00:16:23 +0100 Subject: [PATCH 004/163] Create single file for common consts and update where referenced --- .../themes/enterprise/components/avatar.tsx | 4 +--- .../enterprise/components/hero-post.tsx | 4 +--- .../enterprise/components/post-preview.tsx | 4 +--- .../enterprise/components/searchbar.tsx | 4 +--- .../enterprise/components/secondary-post.tsx | 4 +--- .../themes/enterprise/pages/api/og/home.tsx | 6 ++--- .../themes/enterprise/pages/api/og/post.tsx | 9 +++----- .../themes/enterprise/pages/index.tsx | 22 ++++++++++++------- .../themes/enterprise/pages/series/[slug].tsx | 4 +--- .../themes/enterprise/utils/const/index.ts | 5 +++++ 10 files changed, 30 insertions(+), 36 deletions(-) create mode 100644 packages/blog-starter-kit/themes/enterprise/utils/const/index.ts diff --git a/packages/blog-starter-kit/themes/enterprise/components/avatar.tsx b/packages/blog-starter-kit/themes/enterprise/components/avatar.tsx index 39e21f8ab..a52ed1426 100644 --- a/packages/blog-starter-kit/themes/enterprise/components/avatar.tsx +++ b/packages/blog-starter-kit/themes/enterprise/components/avatar.tsx @@ -1,7 +1,5 @@ import { resizeImage } from '@starter-kit/utils/image'; - -const DEFAULT_AVATAR = - 'https://cdn.hashnode.com/res/hashnode/image/upload/v1659089761812/fsOct5gl6.png'; +import { DEFAULT_AVATAR } from '../utils/const'; type Props = { username: string; diff --git a/packages/blog-starter-kit/themes/enterprise/components/hero-post.tsx b/packages/blog-starter-kit/themes/enterprise/components/hero-post.tsx index 5c2bcfddd..6ad94e290 100644 --- a/packages/blog-starter-kit/themes/enterprise/components/hero-post.tsx +++ b/packages/blog-starter-kit/themes/enterprise/components/hero-post.tsx @@ -1,5 +1,6 @@ import { resizeImage } from '@starter-kit/utils/image'; import Link from 'next/link'; +import { DEFAULT_COVER } from '../utils/const'; import { CoverImage } from './cover-image'; import { DateFormatter } from './date-formatter'; @@ -11,9 +12,6 @@ type Props = { slug: string; }; -const DEFAULT_COVER = - 'https://cdn.hashnode.com/res/hashnode/image/upload/v1683525272978/MB5H_kgOC.png?auto=format'; - export const HeroPost = ({ title, coverImage, date, excerpt, slug }: Props) => { const postURL = `/${slug}`; diff --git a/packages/blog-starter-kit/themes/enterprise/components/post-preview.tsx b/packages/blog-starter-kit/themes/enterprise/components/post-preview.tsx index 75fa20bc1..c5b290e9b 100644 --- a/packages/blog-starter-kit/themes/enterprise/components/post-preview.tsx +++ b/packages/blog-starter-kit/themes/enterprise/components/post-preview.tsx @@ -1,6 +1,7 @@ import { resizeImage } from '@starter-kit/utils/image'; import Link from 'next/link'; import { User } from '../generated/graphql'; +import { DEFAULT_COVER } from '../utils/const'; import { CoverImage } from './cover-image'; import { DateFormatter } from './date-formatter'; @@ -15,9 +16,6 @@ type Props = { slug: string; }; -const DEFAULT_COVER = - 'https://cdn.hashnode.com/res/hashnode/image/upload/v1683525272978/MB5H_kgOC.png?auto=format'; - export const PostPreview = ({ title, coverImage, date, excerpt, slug }: Props) => { const postURL = `/${slug}`; diff --git a/packages/blog-starter-kit/themes/enterprise/components/searchbar.tsx b/packages/blog-starter-kit/themes/enterprise/components/searchbar.tsx index b45e80ca3..0fee5f8cd 100644 --- a/packages/blog-starter-kit/themes/enterprise/components/searchbar.tsx +++ b/packages/blog-starter-kit/themes/enterprise/components/searchbar.tsx @@ -7,6 +7,7 @@ import { SearchPostsOfPublicationQuery, SearchPostsOfPublicationQueryVariables, } from '../generated/graphql'; +import { DEFAULT_COVER } from '../utils/const'; import { useAppContext } from './contexts/appContext'; import { CoverImage } from './cover-image'; @@ -15,9 +16,6 @@ const NO_OF_SEARCH_RESULTS = 5; type Post = SearchPostsOfPublicationQuery['searchPostsOfPublication']['edges'][0]['node']; -const DEFAULT_COVER = - 'https://cdn.hashnode.com/res/hashnode/image/upload/v1683525272978/MB5H_kgOC.png?auto=format'; - export const Search = () => { const { publication } = useAppContext(); diff --git a/packages/blog-starter-kit/themes/enterprise/components/secondary-post.tsx b/packages/blog-starter-kit/themes/enterprise/components/secondary-post.tsx index a7bf1ccf1..bf4fb852d 100644 --- a/packages/blog-starter-kit/themes/enterprise/components/secondary-post.tsx +++ b/packages/blog-starter-kit/themes/enterprise/components/secondary-post.tsx @@ -1,5 +1,6 @@ import { resizeImage } from '@starter-kit/utils/image'; import Link from 'next/link'; +import { DEFAULT_COVER } from '../utils/const'; import { CoverImage } from './cover-image'; import { DateFormatter } from './date-formatter'; @@ -11,9 +12,6 @@ type Props = { slug: string; }; -const DEFAULT_COVER = - 'https://cdn.hashnode.com/res/hashnode/image/upload/v1683525272978/MB5H_kgOC.png?auto=format'; - export const SecondaryPost = ({ title, coverImage, date, excerpt, slug }: Props) => { const postURL = `/${slug}`; diff --git a/packages/blog-starter-kit/themes/enterprise/pages/api/og/home.tsx b/packages/blog-starter-kit/themes/enterprise/pages/api/og/home.tsx index 110b9bfb2..a5f265ef7 100644 --- a/packages/blog-starter-kit/themes/enterprise/pages/api/og/home.tsx +++ b/packages/blog-starter-kit/themes/enterprise/pages/api/og/home.tsx @@ -1,9 +1,7 @@ import { resizeImage } from '@starter-kit/utils/image'; -import { type NextRequest } from 'next/server'; import { ImageResponse } from '@vercel/og'; - -const DEFAULT_AVATAR = - 'https://cdn.hashnode.com/res/hashnode/image/upload/v1659089761812/fsOct5gl6.png'; +import { type NextRequest } from 'next/server'; +import { DEFAULT_AVATAR } from '../../../utils/const'; export const config = { runtime: 'edge', diff --git a/packages/blog-starter-kit/themes/enterprise/pages/api/og/post.tsx b/packages/blog-starter-kit/themes/enterprise/pages/api/og/post.tsx index 07684d970..78404f092 100644 --- a/packages/blog-starter-kit/themes/enterprise/pages/api/og/post.tsx +++ b/packages/blog-starter-kit/themes/enterprise/pages/api/og/post.tsx @@ -1,9 +1,7 @@ import { resizeImage } from '@starter-kit/utils/image'; -import { type NextRequest } from 'next/server'; import { ImageResponse } from '@vercel/og'; - -const DEFAULT_AVATAR = - 'https://cdn.hashnode.com/res/hashnode/image/upload/v1659089761812/fsOct5gl6.png'; +import { type NextRequest } from 'next/server'; +import { DEFAULT_AVATAR } from '../../../utils/const'; export const config = { runtime: 'edge', @@ -84,8 +82,7 @@ export default async function handler(req: NextRequest) { >
- {/* if author image is not available, use the default author image. Source below */} - {/* https://cdn.hashnode.com/res/hashnode/image/upload/v1659089761812/fsOct5gl6.png?auto=compress */} + {/* if author image is not available, use the default author image (DEFAULT_AVATAR) from const */} name
{/* Author name, even if it's team */} diff --git a/packages/blog-starter-kit/themes/enterprise/pages/index.tsx b/packages/blog-starter-kit/themes/enterprise/pages/index.tsx index 364b798ba..bad743f86 100644 --- a/packages/blog-starter-kit/themes/enterprise/pages/index.tsx +++ b/packages/blog-starter-kit/themes/enterprise/pages/index.tsx @@ -28,6 +28,7 @@ import { PostsByPublicationQueryVariables, PublicationFragment, } from '../generated/graphql'; +import { DEFAULT_COVER } from '../utils/const'; const SubscribeForm = dynamic(() => import('../components/subscribe-form').then((mod) => mod.SubscribeForm), @@ -71,10 +72,7 @@ export default function Index({ publication, initialAllPosts, initialPageInfo }: - - - + + + Date: Sun, 22 Oct 2023 00:17:27 +0100 Subject: [PATCH 005/163] Create single file for common consts and update where referenced --- .../themes/personal/components/avatar.tsx | 3 +-- .../themes/personal/pages/api/og/home.tsx | 5 ++--- .../themes/personal/pages/api/og/post.tsx | 8 +++----- .../blog-starter-kit/themes/personal/utils/const/index.ts | 2 ++ 4 files changed, 8 insertions(+), 10 deletions(-) create mode 100644 packages/blog-starter-kit/themes/personal/utils/const/index.ts diff --git a/packages/blog-starter-kit/themes/personal/components/avatar.tsx b/packages/blog-starter-kit/themes/personal/components/avatar.tsx index cd9411cd0..fde17ab80 100644 --- a/packages/blog-starter-kit/themes/personal/components/avatar.tsx +++ b/packages/blog-starter-kit/themes/personal/components/avatar.tsx @@ -1,6 +1,5 @@ import { resizeImage } from '@starter-kit/utils/image'; -const DEFAULT_AVATAR = - 'https://cdn.hashnode.com/res/hashnode/image/upload/v1659089761812/fsOct5gl6.png'; +import { DEFAULT_AVATAR } from '../utils/const'; type Props = { username: string; diff --git a/packages/blog-starter-kit/themes/personal/pages/api/og/home.tsx b/packages/blog-starter-kit/themes/personal/pages/api/og/home.tsx index 352fe3f99..a5f265ef7 100644 --- a/packages/blog-starter-kit/themes/personal/pages/api/og/home.tsx +++ b/packages/blog-starter-kit/themes/personal/pages/api/og/home.tsx @@ -1,8 +1,7 @@ import { resizeImage } from '@starter-kit/utils/image'; -import { type NextRequest } from 'next/server'; import { ImageResponse } from '@vercel/og'; - -const DEFAULT_AVATAR = 'https://cdn.hashnode.com/res/hashnode/image/upload/v1659089761812/fsOct5gl6.png'; +import { type NextRequest } from 'next/server'; +import { DEFAULT_AVATAR } from '../../../utils/const'; export const config = { runtime: 'edge', diff --git a/packages/blog-starter-kit/themes/personal/pages/api/og/post.tsx b/packages/blog-starter-kit/themes/personal/pages/api/og/post.tsx index 1bbb7c7a9..78404f092 100644 --- a/packages/blog-starter-kit/themes/personal/pages/api/og/post.tsx +++ b/packages/blog-starter-kit/themes/personal/pages/api/og/post.tsx @@ -1,8 +1,7 @@ import { resizeImage } from '@starter-kit/utils/image'; -import { type NextRequest } from 'next/server'; import { ImageResponse } from '@vercel/og'; - -const DEFAULT_AVATAR = 'https://cdn.hashnode.com/res/hashnode/image/upload/v1659089761812/fsOct5gl6.png'; +import { type NextRequest } from 'next/server'; +import { DEFAULT_AVATAR } from '../../../utils/const'; export const config = { runtime: 'edge', @@ -83,8 +82,7 @@ export default async function handler(req: NextRequest) { >
- {/* if author image is not available, use the default author image. Source below */} - {/* https://cdn.hashnode.com/res/hashnode/image/upload/v1659089761812/fsOct5gl6.png?auto=compress */} + {/* if author image is not available, use the default author image (DEFAULT_AVATAR) from const */} name
{/* Author name, even if it's team */} diff --git a/packages/blog-starter-kit/themes/personal/utils/const/index.ts b/packages/blog-starter-kit/themes/personal/utils/const/index.ts new file mode 100644 index 000000000..6f31a9f57 --- /dev/null +++ b/packages/blog-starter-kit/themes/personal/utils/const/index.ts @@ -0,0 +1,2 @@ +export const DEFAULT_AVATAR = + 'https://cdn.hashnode.com/res/hashnode/image/upload/v1659089761812/fsOct5gl6.png'; From 59b41c321d36e45669e30b8771ab1ea94aee0080 Mon Sep 17 00:00:00 2001 From: Victorious <61851642+victornwakpa@users.noreply.github.com> Date: Tue, 24 Oct 2023 03:36:27 +0100 Subject: [PATCH 006/163] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 593a5cffe..3c6081ba3 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Blog Starter Kit lets you instantly deploy a Next.js and Tailwind powered fronte ### Step 1 -The recommended approach is depoying to Vercel. If you don't have an account already, sign up for a free plan. +The recommended approach is deploying to Vercel. If you don't have an account already, sign up for a free plan. - Fork this repo - Create a new project on Vercel and connect this repo @@ -113,7 +113,7 @@ async function proxyBlog(request) { } ``` -Be sure to replace the values of `subpath` and `blogBaseUrl` in the above snippet. This way cloudflare will proxy all the requests starting with `youdomain.com/blog` to your headless blog, and other requests will hit your origin as usual. +Be sure to replace the values of `subpath` and `blogBaseUrl` in the above snippet. This way cloudflare will proxy all the requests starting with `yourdomain.com/blog` to your headless blog, and other requests will hit your origin as usual. If your main domain is hosted elsewhere, you need to involve engineers from your team to create above rewrites. From a81eeb6a665dd180c3835e7851d4b3e2bdf3f950 Mon Sep 17 00:00:00 2001 From: Harsh Date: Thu, 26 Oct 2023 10:50:27 +0530 Subject: [PATCH 007/163] Added hashnode theme with header navigation --- packages/blog-starter-kit/themes/enterprise/generated/graphql.ts | 1 + .../blog-starter-kit/themes/enterprise/generated/schema.graphql | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/blog-starter-kit/themes/enterprise/generated/graphql.ts b/packages/blog-starter-kit/themes/enterprise/generated/graphql.ts index 0618cb15a..d70e81eb7 100644 --- a/packages/blog-starter-kit/themes/enterprise/generated/graphql.ts +++ b/packages/blog-starter-kit/themes/enterprise/generated/graphql.ts @@ -1675,6 +1675,7 @@ export enum Scope { PublicationAdmin = 'publication_admin', RecommendPublications = 'recommend_publications', Signup = 'signup', + UpdatePost = 'update_post', WebhookAdmin = 'webhook_admin', WritePost = 'write_post', WriteSeries = 'write_series' diff --git a/packages/blog-starter-kit/themes/enterprise/generated/schema.graphql b/packages/blog-starter-kit/themes/enterprise/generated/schema.graphql index ca2ed5f00..3ef871fdd 100644 --- a/packages/blog-starter-kit/themes/enterprise/generated/schema.graphql +++ b/packages/blog-starter-kit/themes/enterprise/generated/schema.graphql @@ -1684,6 +1684,7 @@ enum Scope { publication_admin recommend_publications signup + update_post webhook_admin write_post write_series From 60b303abbcef0849095c9ed05cdcde3440f5a699 Mon Sep 17 00:00:00 2001 From: Victorious <61851642+victornwakpa@users.noreply.github.com> Date: Thu, 26 Oct 2023 17:25:57 +0100 Subject: [PATCH 008/163] Update footer.tsx Corrected the text color of the footer publication-title. It wasn't showing in light mode --- .../blog-starter-kit/themes/enterprise/components/footer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/blog-starter-kit/themes/enterprise/components/footer.tsx b/packages/blog-starter-kit/themes/enterprise/components/footer.tsx index b373dd40b..067eda677 100644 --- a/packages/blog-starter-kit/themes/enterprise/components/footer.tsx +++ b/packages/blog-starter-kit/themes/enterprise/components/footer.tsx @@ -20,7 +20,7 @@ export const Footer = () => {
) : ( -

+

{publication.title}

)} From 3b0f429893d910dd50a87106022cf587581484c5 Mon Sep 17 00:00:00 2001 From: Victorious <61851642+victornwakpa@users.noreply.github.com> Date: Thu, 26 Oct 2023 17:35:48 +0100 Subject: [PATCH 009/163] Update footer.tsx Changed publication.title color --- .../blog-starter-kit/themes/enterprise/components/footer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/blog-starter-kit/themes/enterprise/components/footer.tsx b/packages/blog-starter-kit/themes/enterprise/components/footer.tsx index 067eda677..f6009a153 100644 --- a/packages/blog-starter-kit/themes/enterprise/components/footer.tsx +++ b/packages/blog-starter-kit/themes/enterprise/components/footer.tsx @@ -20,7 +20,7 @@ export const Footer = () => {
) : ( -

+

{publication.title}

)} From 30e424c2eebf6bd2e8df027beb6bf4d7c03921f9 Mon Sep 17 00:00:00 2001 From: Sandeep Panda Date: Thu, 26 Oct 2023 13:14:17 -0700 Subject: [PATCH 010/163] Update README.md Include chatgql.com --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 04768ef46..8fcae151f 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,7 @@ If you prefer to build your frontend from scratch, you can use our public GraphQ - [Docs](https://apidocs.hashnode.com) - [GraphQL Playground](https://gql.hashnode.com) +- [Generate queries/mutations by talking to AI](https://chatgql.com/chat?url=https://gql.hashnode.com) ## Demo Videos From b90a4e3a1c52dc41e903ffcbec47df58d88f7903 Mon Sep 17 00:00:00 2001 From: Victorious <61851642+victornwakpa@users.noreply.github.com> Date: Sat, 28 Oct 2023 06:43:30 +0100 Subject: [PATCH 011/163] Update README.md Changed the screenshot to reflect both the enterprise and the personal theme --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 04768ef46..8766c2efb 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,9 @@ The recommended approach is deploying to Vercel. If you don't have an account al - Fork this repo - Create a new project on Vercel and connect this repo - It's a monorepo. So, choose either `packages/blog-starter-kit/themes/enterprise` or `packages/blog-starter-kit/themes/personal` as the root directory while importing on Vercel. - ![selecting the directory to deploy a monorepo](https://cdn.hashnode.com/res/hashnode/image/upload/v1695083263935/T5bByLxZT.png?w=500&h=800&auto=format) + + ![selecting the directory to deploy a monorepo](https://github.com/victornwakpa/starter-kit/assets/61851642/f6d25a80-065a-48a2-9501-4047de544eb5) + - Choose `Next.js` as framework preset (just above Root Directory setting). - Set the following environment variables From c61c873b36410e4fa7dbc38bd37b9986ece58ca9 Mon Sep 17 00:00:00 2001 From: Ayodele Samuel Adebayo Date: Sat, 28 Oct 2023 09:42:58 +0100 Subject: [PATCH 012/163] Add mobile sidebar to enterprise blog --- .../themes/enterprise/components/header.tsx | 60 ++++++------ .../components/icons/svgs/CloseSVG.js | 11 +++ .../components/icons/svgs/HamburgerSVG.js | 2 +- .../components/publication-logo.tsx | 33 +++++++ .../themes/enterprise/components/sidebar.tsx | 95 +++++++++++++++++++ .../enterprise/components/social-links.tsx | 8 +- .../themes/enterprise/generated/graphql.ts | 3 + .../enterprise/generated/schema.graphql | 5 + .../themes/enterprise/package.json | 1 + 9 files changed, 183 insertions(+), 35 deletions(-) create mode 100644 packages/blog-starter-kit/themes/enterprise/components/icons/svgs/CloseSVG.js create mode 100644 packages/blog-starter-kit/themes/enterprise/components/publication-logo.tsx create mode 100644 packages/blog-starter-kit/themes/enterprise/components/sidebar.tsx diff --git a/packages/blog-starter-kit/themes/enterprise/components/header.tsx b/packages/blog-starter-kit/themes/enterprise/components/header.tsx index caf450837..6d8c52bd1 100644 --- a/packages/blog-starter-kit/themes/enterprise/components/header.tsx +++ b/packages/blog-starter-kit/themes/enterprise/components/header.tsx @@ -1,10 +1,12 @@ import * as DropdownMenu from '@radix-ui/react-dropdown-menu'; -import { resizeImage } from '@starter-kit/utils/image'; -import Link from 'next/link'; +import { useState } from 'react'; import { PublicationNavbarItem } from '../generated/graphql'; import { Button } from './button'; import { Container } from './container'; import { useAppContext } from './contexts/appContext'; +import HamburgerSVG from './icons/svgs/HamburgerSVG'; +import { PublicationLogo } from './publication-logo'; +import PublicationSidebar from './sidebar'; function hasUrl( navbarItem: PublicationNavbarItem, @@ -14,12 +16,17 @@ function hasUrl( export const Header = () => { const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || '/'; + const [isSidebarVisible, setIsSidebarVisible] = useState(); const { publication } = useAppContext(); const PUBLICATION_LOGO = publication.preferences.darkMode?.logo || publication.preferences.logo; const navbarItems = publication.preferences.navbarItems.filter(hasUrl); const visibleItems = navbarItems.slice(0, 3); const hiddenItems = navbarItems.slice(3); + const toggleSidebar = () => { + setIsSidebarVisible((prevVisibility) => !prevVisibility); + }; + const navList = (