Skip to content

Commit

Permalink
Add blog homepage
Browse files Browse the repository at this point in the history
  • Loading branch information
letelete committed Jul 8, 2024
1 parent aa6de00 commit 071225a
Show file tree
Hide file tree
Showing 32 changed files with 501 additions and 146 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"framer-motion": "^11.2.11",
"lodash-es": "^4.17.21",
"lottie-web": "^5.12.2",
"lucide-react": "^0.340.0",
"lucide-react": "^0.402.0",
"next": "14.1.1",
"next-mdx-remote": "^4.4.1",
"nuqs": "^1.17.1",
Expand Down
10 changes: 5 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 21 additions & 2 deletions src/app/(root)/blog/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,28 @@
import { getAllContent } from '~lib/content/provider';
import { ContentType, getAllContent } from '~lib/content/provider';

import { Blog } from '~modules/blog';

const HIGHLIGHTED_CONTENT_PRIORITY = [
'article',
'youtube-video',
'talk',
] as ContentType[];

export default async function BlogPage() {
const contents = await getAllContent();
const publishedContent = contents.filter((content) => content.published);
const highlightedContents = publishedContent
.sort((a, b) => {
const aPriority = HIGHLIGHTED_CONTENT_PRIORITY.indexOf(a.type);
const bPriority = HIGHLIGHTED_CONTENT_PRIORITY.indexOf(b.type);
return aPriority - bPriority;
})
.slice(0, 3);

return <Blog contents={contents} />;
return (
<Blog
contents={publishedContent}
highlightedContents={highlightedContents}
/>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ const DynamicWeightOnHoverText = ({

return (
<>
{text.split('').map((char) => (
{text.split('').map((char, idx) => (
<motion.span
aria-hidden
key={`${id}:${char}`}
key={`${id}:${char}:${idx}`}
whileHover={{
fontWeight: 700,
transition: { type: 'spring', duration: 0.2, bounce: 0 },
}}
transition={{ type: 'spring', duration: 1, bounce: 0 }}
aria-hidden
{...rest}
>
{char}
Expand Down
23 changes: 22 additions & 1 deletion src/components/ui/atoms/icon/custom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,34 @@ import { createLucideIcon } from 'lucide-react';
* StackOverflowIcon
* -----------------------------------------------------------------------------------------------*/

export const StackOverflowIcon = createLucideIcon('stackoverflow', [
const StackOverflowIcon = createLucideIcon('stackoverflow', [
[
'path',
{
d: 'M9.5 9.5L16.5 13M12 5.5L17.5 10M8 13.5L15.5 15.5M4 16C4 16 4 21 4 21.5C4 22 5.5 22 5.5 22H17.5C17.5 22 19 22 19 21.5C19 21 19 18.1479 19 16M15 2L19.5 8.5M8 18H15.5',
key: 'p1',
},
],
]);

StackOverflowIcon.displayName = 'StackOverflowIcon';

/* -------------------------------------------------------------------------------------------------
* RedditIcon
* -----------------------------------------------------------------------------------------------*/

const RedditIcon = createLucideIcon('reddit', [
[
'path',
{
d: 'M8 17.5c4.17 3 8 0 8 0m-4.5-9h.67c5 0 6.33 1.5 6.33 1.5 2.5-1.5 5.5 2 3 4 0 2.5-1.83 7-9.33 7S3 17 3 14.5c-3.5-2.5-.5-6 2.5-4.5 0 0 1.52-1.37 6-1.5Zm0 0 1.5-6 3 .5M9.5 13.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Zm7.5 0a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Zm3-10a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Z',
key: 'p1',
},
],
]);

RedditIcon.displayName = 'RedditIcon';

/* -----------------------------------------------------------------------------------------------*/

export { StackOverflowIcon, RedditIcon };
11 changes: 9 additions & 2 deletions src/components/ui/atoms/icon/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import {
Linkedin,
LucideProps,
Mail,
MessageCircle,
MicVocal,
Rocket,
Send,
Square,
Twitter,
Expand All @@ -19,7 +22,7 @@ import {
} from 'lucide-react';
import { FC } from 'react';

import { StackOverflowIcon } from '~ui/atoms/icon/custom';
import { RedditIcon, StackOverflowIcon } from '~ui/atoms/icon/custom';

import { cn, tw } from '~utils/style';

Expand Down Expand Up @@ -72,12 +75,16 @@ const icons = new Map([
['lightbulb', Lightbulb],
['linkedin', Linkedin],
['mail', Mail],
['message-circle', MessageCircle],
['mic-vocal', MicVocal],
['reddit', RedditIcon],
['rocket', Rocket],
['send', Send],
['square', Square],
['stackoverflow', StackOverflowIcon],
['twitter', Twitter],
['volume-2', Volume2],
['youtube', Youtube],
['stackoverflow', StackOverflowIcon],
] as const satisfies readonly (readonly [string, FC<LucideProps>])[]);

/* -----------------------------------------------------------------------------------------------*/
Expand Down
2 changes: 2 additions & 0 deletions src/components/ui/atoms/responsive/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import {
Children,
ComponentProps,
ForwardedRef,
ReactElement,
ReactNode,
ReactPropTypes,
cloneElement,
forwardRef,
} from 'react';
Expand Down
7 changes: 5 additions & 2 deletions src/components/ui/atoms/tag/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import { cn } from '~utils/style';

export interface TagProps extends ButtonProps {
label: string;
count?: number;
selectable?: boolean;
selected?: boolean;
}

export const Tag = ({
label,
count,
selectable,
selected,
className,
Expand All @@ -27,15 +29,16 @@ export const Tag = ({
return (
<Button
className={cn(
'text-foreground-secondary font-normal transition-colors',
selected && 'text-accent',
'font-normal text-ctx-accent-secondary transition-opacity',
selected && 'bg-ctx-accent-primary',
className
)}
variant='link'
size='inline'
{...rest}
>
#{label}
{count !== undefined ? ` (${count})` : null}
</Button>
);
};
22 changes: 19 additions & 3 deletions src/components/ui/molecules/content-card/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ import {
useCallback,
} from 'react';

import { ContentType, contentTypes } from '~lib/content/provider';

import { Card, CardProps } from '~ui/atoms/card';
import { TextSkeleton } from '~ui/atoms/skeleton';
import { Typography } from '~ui/atoms/typography';
import { ContentIcon } from '~ui/molecules/content-icon';

import { cn } from '~utils/style';
import { cn, tw } from '~utils/style';

/* -------------------------------------------------------------------------------------------------
* ContentCard
Expand All @@ -27,6 +30,7 @@ interface ContentCardProps extends CardProps {
title?: string;
display?: ReactNode;
displayPlaceholder?: ReactNode;
contentType?: ContentType;
}

const ContentCard = ({
Expand All @@ -35,6 +39,7 @@ const ContentCard = ({
title,
display,
displayPlaceholder,
contentType,
className,
...rest
}: ContentCardProps) => {
Expand All @@ -51,7 +56,7 @@ const ContentCard = ({
return (
<Typography
title={title}
className='mt-1 line-clamp-2 h-[calc(2em*1.5)] w-full text-left leading-[1.5]'
className='mt-1 line-clamp-3 h-[calc(3em*1.25)] w-full text-left leading-5 sm:line-clamp-2 sm:h-[calc(2em*1.5)] sm:leading-6'
prose={false}
balance
>
Expand Down Expand Up @@ -81,13 +86,14 @@ const ContentCard = ({
return (
<Card asChild className={cn('flex flex-col', className)} {...rest}>
<MotionLink
className='relative'
href={href}
whileHover={{ y: -10 }}
whileTap={{ scale: 0.9, opacity: 0.5 }}
transition={{ type: 'spring', duration: 0.2 }}
>
<Typography
className='line-clamp-1 w-full text-left uppercase'
className='line-clamp-2 w-full text-left uppercase sm:line-clamp-1'
variant='sm'
color='secondary'
weight='bold'
Expand All @@ -100,6 +106,16 @@ const ContentCard = ({
{renderTitle()}

{renderDisplay()}

{contentType ? (
<div className='absolute bottom-2 left-2 aspect-square h-8 w-8 rounded-full bg-ctx-button p-2 md:bottom-3 md:left-3 md:h-12 md:w-12 md:p-3'>
<ContentIcon
size={'100%'}
color={tw.theme.colors.ctx.button.fg.solid}
contentType={contentType}
/>
</div>
) : null}
</MotionLink>
</Card>
);
Expand Down
34 changes: 34 additions & 0 deletions src/components/ui/molecules/content-icon/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useMemo } from 'react';

import { ContentType } from '~lib/content/provider';

import { Icon, IconName, IconProps } from '~ui/atoms/icon';

/* -------------------------------------------------------------------------------------------------
* ContentIcon
* -----------------------------------------------------------------------------------------------*/

const contentTypeToIconName: Record<ContentType, IconName> = {
article: 'message-circle',
'youtube-video': 'youtube',
talk: 'mic-vocal',
};

interface ContentIconProps extends Omit<IconProps, 'name'> {
contentType: ContentType;
}

const ContentIcon = ({ contentType, ...rest }: ContentIconProps) => {
const name = useMemo(() => {
return contentTypeToIconName[contentType];
}, [contentType]);

return <Icon name={name} {...rest} />;
};

ContentIcon.displayName = 'ContentIcon';

/* -----------------------------------------------------------------------------------------------*/

export { ContentIcon };
export type { ContentIconProps };
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,29 @@ InlinePlatformRedirectStackOverflow.displayName =

/* -----------------------------------------------------------------------------------------------*/

const InlinePlatformRedirectReddit = () => {
return (
<InlinePlatformRedirectWithIcon
label='Reddit'
link={SOCIALS.reddit.url}
icon='reddit'
buttonProps={{ className: 'hover:text-socials-reddit' }}
iconProps={{
color: tw.theme.colors.socials.reddit,
}}
/>
);
};

InlinePlatformRedirectReddit.displayName = 'InlinePlatformRedirectReddit';

/* -----------------------------------------------------------------------------------------------*/

export {
InlinePlatformRedirectWithIcon,
InlinePlatformRedirectTwitter,
InlinePlatformRedirectGitHub,
InlinePlatformRedirectStackOverflow,
InlinePlatformRedirectReddit,
};
export type { InlinePlatformRedirectWithIconProps };
2 changes: 1 addition & 1 deletion src/components/ui/molecules/section/section-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const SectionHeader = ({
</Typography>

{subtitle && (
<Typography color='secondary' className='text-left'>
<Typography color='secondary' className='text-right'>
{subtitle}
</Typography>
)}
Expand Down
Loading

0 comments on commit 071225a

Please sign in to comment.