forked from Hashnode/starter-kit
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds co authors details below post subtitle for enterprise theme
- Loading branch information
Showing
9 changed files
with
380 additions
and
11 deletions.
There are no files selected for viewing
85 changes: 85 additions & 0 deletions
85
packages/blog-starter-kit/themes/enterprise/components/co-authors-modal.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { Button } from './button'; | ||
import CloseSVG from './icons/svgs/CloseSVG'; | ||
import * as DialogPrimitive from '@radix-ui/react-dialog'; | ||
import CustomScrollArea from './scroll-area'; | ||
import { DEFAULT_AVATAR } from '../utils/const'; | ||
import { ResizableImage } from './resizable-image'; | ||
import { useAppContext } from './contexts/appContext'; | ||
import { PostFullFragment } from '../generated/graphql'; | ||
|
||
type CoAuthorsModalProps = { | ||
closeModal: () => void; | ||
}; | ||
|
||
const AuthorCard = ({ author }: { author: PostFullFragment['author']; }) => { | ||
|
||
return ( | ||
<div className="flex flex-row items-center justify-between" key={author.id.toString()}> | ||
<div | ||
className="flex w-full flex-wrap items-center justify-between overflow-hidden px-0 py-2.5" | ||
> | ||
<div className="flex flex-wrap items-center overflow-hidden"> | ||
<a href={`https://hashnode.com/@${author.username}`} title={author.name} className="mr-2 w-8"> | ||
<ResizableImage | ||
src={author.profilePicture || DEFAULT_AVATAR} | ||
resize={{ w: 200, h: 200, c: 'face' }} | ||
className="mr-3 h-8 w-8 rounded-full" | ||
/> | ||
</a> | ||
<div className="flex flex-row items-center text-clip"> | ||
<a | ||
href={`https://hashnode.com/@${author.username}`} | ||
title={author.name} | ||
className="truncate font-sans text-sm font-medium text-slate-700 dark:text-slate-200" | ||
> | ||
{author.name} | ||
</a> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default function CoAuthorsModal({ closeModal }: CoAuthorsModalProps) { | ||
const { post } = useAppContext(); | ||
const authors = [post?.author, ...(post?.coAuthors || [])]; | ||
|
||
return ( | ||
<DialogPrimitive.Root open> | ||
<DialogPrimitive.Portal> | ||
<DialogPrimitive.Overlay | ||
onClick={closeModal} | ||
className="fixed inset-0 z-50 bg-slate-900 opacity-50 transition-opacity duration-300 ease-out dark:bg-slate-600" | ||
/> | ||
<DialogPrimitive.Content | ||
onEscapeKeyDown={closeModal} | ||
className="fixed bottom-0 left-0 right-0 z-50 flex w-full max-w-[1200px] flex-col items-center overflow-hidden rounded-b-none rounded-t-lg border-slate-200 bg-white text-slate-700 dark:border-slate-800 dark:bg-slate-900 dark:text-slate-50 md:bottom-50 md:left-50 md:w-96 md:-translate-x-1/2 md:translate-y-1/2 md:rounded-xl lg:w-108 xl:w-116" | ||
> | ||
<DialogPrimitive.DialogTitle className="w-full px-6 py-4 text-lg font-semibold"> | ||
Authors in this article | ||
</DialogPrimitive.DialogTitle> | ||
<DialogPrimitive.Close className="absolute right-2 top-4 text-slate-900 dark:text-slate-50" asChild> | ||
<Button | ||
type="outline" | ||
label="" | ||
icon={<CloseSVG className="h-5 w-5 fill-current" />} | ||
className="rounded-xl !border-transparent !px-3 !py-2 hover:bg-neutral-800 dark:text-white" | ||
onClick={closeModal} | ||
/> | ||
</DialogPrimitive.Close> | ||
<CustomScrollArea> | ||
<div className="px-6 pb-8"> | ||
{authors.map((author) => { | ||
if (!author) { | ||
return null; | ||
} | ||
return <AuthorCard author={author} key={author.id.toString()} />; | ||
})} | ||
</div> | ||
</CustomScrollArea> | ||
</DialogPrimitive.Content> | ||
</DialogPrimitive.Portal> | ||
</DialogPrimitive.Root> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
packages/blog-starter-kit/themes/enterprise/components/profile-image.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import React from 'react'; | ||
import { twMerge } from 'tailwind-merge'; | ||
import Image from 'next/legacy/image'; | ||
|
||
import { resizeImage } from '@starter-kit/utils/image'; | ||
import { DEFAULT_AVATAR } from '../utils/const'; | ||
|
||
export default class ProfileImage extends React.Component { | ||
componentDidMount() { | ||
if (!this.props.user) { | ||
return; | ||
} | ||
if (this.props.user.isDeactivated) { | ||
return; | ||
} | ||
} | ||
|
||
render() { | ||
const user = this.props.user; | ||
const blogURL = this.props.blogURL; | ||
return ( | ||
<a | ||
href={ | ||
blogURL | ||
? blogURL | ||
: user && !user.isDeactivated | ||
? `https://hashnode.com/@${user.username}` | ||
: this.props.postUrlForAnonymous | ||
? this.props.postUrlForAnonymous | ||
: '#' | ||
} | ||
ref={(c) => { | ||
this.profileImage = c; | ||
}} | ||
className={`relative block h-full w-full`} | ||
> | ||
<Image | ||
className={twMerge(this.props.className, `relative z-20 block w-full rounded-full`)} | ||
src={ | ||
user && user.profilePicture | ||
? resizeImage(user.profilePicture, { w: this.props.width || 70, h: this.props.height || 70, c: 'face' }) | ||
: DEFAULT_AVATAR | ||
} | ||
width={this.props.width ? parseInt(this.props.width) : 70} | ||
height={this.props.height ? parseInt(this.props.height) : 70} | ||
// resize={{ | ||
// w: this.props.width ? parseInt(this.props.width) : 70, | ||
// h: this.props.height ? parseInt(this.props.height) : 70, | ||
// c: 'face', | ||
// }} | ||
alt={user ? user.name + "'s photo" : undefined} | ||
/> | ||
</a> | ||
); | ||
} | ||
} |
67 changes: 67 additions & 0 deletions
67
packages/blog-starter-kit/themes/enterprise/components/progressive-image.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import React from 'react'; | ||
import { resizeImage } from '@starter-kit/utils/image'; | ||
|
||
import { DEFAULT_AVATAR } from '../utils/const'; | ||
import { twMerge } from 'tailwind-merge'; | ||
|
||
/** | ||
* Progressive Image Component which loads low resolution version image before loading original | ||
* @param {string} options.src Image source | ||
* @param {string} options.alt Image alt text | ||
* @param {string} options.className Classname string | ||
* @param {...[type]} options.restOfProps Rest of the props passed to the child | ||
*/ | ||
class ProgressiveImage extends React.Component<{ | ||
resize: any; | ||
src: string; | ||
alt: string; | ||
className: string; | ||
css: string; | ||
}> { | ||
image: HTMLImageElement | null = null; | ||
|
||
componentDidMount() { | ||
if (!(window as any).lazySizes && this.image) { | ||
this.image.setAttribute('src', this.image.getAttribute('data-src') || ''); | ||
} | ||
} | ||
|
||
// TODO: Improve type | ||
replaceBadImage = (e: any) => { | ||
// eslint-disable-next-line react/destructuring-assignment | ||
if (this.props.resize && this.props.resize.c !== 'face') { | ||
return; | ||
} | ||
e.target.onerror = null; | ||
e.target.src = DEFAULT_AVATAR; | ||
}; | ||
|
||
render() { | ||
const { src, alt, className, resize = {}, ...restOfProps } = this.props; | ||
|
||
if (!src || src.trim().length === 0) return null; | ||
|
||
const resizedImage = resizeImage(src, resize); | ||
|
||
return ( | ||
<img | ||
data-sizes="auto" | ||
loading="lazy" | ||
src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" | ||
// eslint-disable-next-line no-return-assign | ||
ref={(c) => (this.image = c || null)} | ||
data-src={resizedImage} | ||
width={resize.w} | ||
height={resize.h} | ||
onError={this.replaceBadImage} | ||
alt={alt} | ||
className={twMerge('lazyload block w-full', className)} | ||
{...restOfProps} | ||
/> | ||
); | ||
} | ||
} | ||
|
||
export default ProgressiveImage; | ||
|
||
export { ProgressiveImage }; |
12 changes: 12 additions & 0 deletions
12
packages/blog-starter-kit/themes/enterprise/components/resizable-image.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { ProgressiveImage } from './progressive-image'; | ||
|
||
function ResizableImage(props) { | ||
const { src, alt, resize, className, ...restOfTheProps } = props; | ||
|
||
return ( | ||
<ProgressiveImage alt={alt} src={src || props.default} resize={resize} className={className} {...restOfTheProps} /> | ||
); | ||
} | ||
|
||
export default ResizableImage; | ||
export { ResizableImage }; |
Oops, something went wrong.