From 433224806d640041c86ca59d05efd88cb0b03f35 Mon Sep 17 00:00:00 2001 From: TheoryOfNekomata Date: Sun, 5 May 2024 19:31:43 +0800 Subject: [PATCH] Extract blog data Put blog data to dummy data JSON, render other blog controls. --- packages/web/data.json | 30 +++++ .../components/molecules/BlogItem/index.tsx | 111 ++++++++++++++++++ .../components/molecules/ClockIcon/index.tsx | 28 +++++ .../molecules/EnvisionSection/index.tsx | 2 +- .../src/components/molecules/Icon/index.tsx | 2 +- .../components/molecules/IconText/index.tsx | 31 +++++ .../molecules/MainLandingSection/index.tsx | 11 +- .../molecules/MakeSection/index.tsx | 30 ++--- .../components/organisms/BlogLayout/index.tsx | 57 +++------ packages/web/src/pages/blog/index.tsx | 23 +++- packages/web/src/styles/globals.css | 4 +- 11 files changed, 262 insertions(+), 67 deletions(-) create mode 100644 packages/web/src/components/molecules/BlogItem/index.tsx create mode 100644 packages/web/src/components/molecules/ClockIcon/index.tsx create mode 100644 packages/web/src/components/molecules/IconText/index.tsx diff --git a/packages/web/data.json b/packages/web/data.json index a826c48..5fb0c6f 100644 --- a/packages/web/data.json +++ b/packages/web/data.json @@ -1,4 +1,34 @@ { + "blog": [ + { + "id": 1, + "title": "Article Title", + "createdAt": "2024-03-14T13:37:00.000Z", + "slug": "article-title", + "content": "Excerpt lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam." + }, + { + "id": 2, + "title": "New Article Title", + "createdAt": "2024-02-14T06:09:00.000Z", + "slug": "new-article-title", + "content": "Excerpt lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam." + }, + { + "id": 3, + "title": "Another Article Title", + "createdAt": "2024-01-25T04:20:00.000Z", + "slug": "another-article-title", + "content": "Excerpt lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam." + }, + { + "id": 4, + "title": "Yet Another Article Title", + "createdAt": "2024-01-03T10:10:00.000Z", + "slug": "yet-another-article-title", + "content": "Excerpt lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam." + } + ], "make": [ { "id": 1, diff --git a/packages/web/src/components/molecules/BlogItem/index.tsx b/packages/web/src/components/molecules/BlogItem/index.tsx new file mode 100644 index 0000000..ffa85f4 --- /dev/null +++ b/packages/web/src/components/molecules/BlogItem/index.tsx @@ -0,0 +1,111 @@ +import {IconText} from '@/components/molecules/IconText'; +import {ClockIcon} from '@/components/molecules/ClockIcon'; +import * as WebNavigationReact from '@tesseract-design/web-navigation-react'; +import Link from 'next/link'; +import * as React from 'react'; + +export interface BlogItemProps { + title: string; + createdAt: number | string | Date; + slug: string; + content: string; +} + +export const BlogItem: React.FC = ({ + title, + createdAt, + slug, + content, +}) => { + const dateObj = new Date(createdAt); + const dateFormat = new Intl.DateTimeFormat('en-PH', { + month: 'short', + day: 'numeric', + year: 'numeric', + }).formatToParts(dateObj); + const month = dateFormat.find((f) => f.type === 'month')?.value; + const date = dateFormat.find((f) => f.type === 'day')?.value; + const year = dateFormat.find((f) => f.type === 'year')?.value; + + const timeFormat = new Intl.DateTimeFormat('en-PH', { + hour12: false, + hour: '2-digit', + minute: '2-digit', + }).formatToParts(dateObj); + + const hour = timeFormat.find((v) => v.type === 'hour')?.value; + const minute = timeFormat.find((v) => v.type === 'minute')?.value; + + const timeZoneFormat = new Intl.DateTimeFormat('en-PH', { + timeZoneName: 'shortOffset', + }).formatToParts(dateObj); + + const timeZone = timeZoneFormat.find((v) => v.type === 'timeZoneName')?.value?.replace('GMT', 'UTC'); + + return ( +
+
+

+ + {title} + +

+ +
+
+ {content} +
+
+
+ + Read more + +
+
+
+ ); +} diff --git a/packages/web/src/components/molecules/ClockIcon/index.tsx b/packages/web/src/components/molecules/ClockIcon/index.tsx new file mode 100644 index 0000000..17f7332 --- /dev/null +++ b/packages/web/src/components/molecules/ClockIcon/index.tsx @@ -0,0 +1,28 @@ +import * as React from 'react'; + +export const ClockIconDerivedElementComponent = 'svg' as const; + +export type ClockIconDerivedElement = SVGElementTagNameMap[typeof ClockIconDerivedElementComponent]; + +export interface ClockIconProps extends React.SVGProps { + hour: number; + minute: number; +} + +export const ClockIcon = React.forwardRef(({ + hour, + minute, + className, + ...etcProps +}, forwardedRef) => ( + + + + + +)); diff --git a/packages/web/src/components/molecules/EnvisionSection/index.tsx b/packages/web/src/components/molecules/EnvisionSection/index.tsx index fabcb17..1d361f8 100644 --- a/packages/web/src/components/molecules/EnvisionSection/index.tsx +++ b/packages/web/src/components/molecules/EnvisionSection/index.tsx @@ -21,7 +21,7 @@ export const EnvisionSection: React.FC = ({ span="wide" >
-

+

I {' '} diff --git a/packages/web/src/components/molecules/Icon/index.tsx b/packages/web/src/components/molecules/Icon/index.tsx index 8585e48..0594894 100644 --- a/packages/web/src/components/molecules/Icon/index.tsx +++ b/packages/web/src/components/molecules/Icon/index.tsx @@ -35,7 +35,7 @@ export const Icon = React.forwardRef(({ {...etcProps} ref={forwardedRef} viewBox="0 0 24 24" - className={`w-6 h-6 linejoin-round linecap-round stroke-2 stroke-current fill-none ${className ?? ''}`.trim()} + className={`w-[1.5em] h-[1.5em] linejoin-round linecap-round stroke-2 stroke-current fill-none ${className ?? ''}`.trim()} > {ICONS[name]} diff --git a/packages/web/src/components/molecules/IconText/index.tsx b/packages/web/src/components/molecules/IconText/index.tsx new file mode 100644 index 0000000..5cd4a6e --- /dev/null +++ b/packages/web/src/components/molecules/IconText/index.tsx @@ -0,0 +1,31 @@ +import * as React from 'react'; + +export interface IconTextProps { + icon: React.ReactNode; + topText?: React.ReactNode; + bottomText?: React.ReactNode; +} + +export const IconText: React.FC = ({ + icon, + topText, + bottomText, +}) => ( + + + {icon} + + {' '} + {topText && ( + + {topText} + + )} + {topText && bottomText && ' '} + {bottomText && ( + + {bottomText} + + )} + +); diff --git a/packages/web/src/components/molecules/MainLandingSection/index.tsx b/packages/web/src/components/molecules/MainLandingSection/index.tsx index c26269a..0d10275 100644 --- a/packages/web/src/components/molecules/MainLandingSection/index.tsx +++ b/packages/web/src/components/molecules/MainLandingSection/index.tsx @@ -3,16 +3,11 @@ import Link from 'next/link'; import {Layouts} from '@tesseract-design/viewfinder-react'; import {Brand} from '@/components/molecules/Brand'; import {Pillar} from '@/components/molecules/Pillar'; -import {BackgroundGrid} from '@/components/molecules/BackgroundGrid'; import {Icon} from '@/components/molecules/Icon'; -export interface MainLandingSectionProps { - backgroundImages: string[]; -} +export interface MainLandingSectionProps {} -export const MainLandingSection: React.FC = ({ - backgroundImages -}) => { +export const MainLandingSection: React.FC = () => { const scrollDown: React.MouseEventHandler = React.useCallback((event) => { event.preventDefault(); @@ -38,7 +33,7 @@ export const MainLandingSection: React.FC = ({ className="relative py-24" >
-

+

diff --git a/packages/web/src/components/molecules/MakeSection/index.tsx b/packages/web/src/components/molecules/MakeSection/index.tsx index 35e5b18..2d77cab 100644 --- a/packages/web/src/components/molecules/MakeSection/index.tsx +++ b/packages/web/src/components/molecules/MakeSection/index.tsx @@ -43,21 +43,21 @@ export const MakeSection: React.FC = ({ className="relative" >
-

- - I - {' '} - - make. - - +

+ + I + {' '} + + make. + +

Software
diff --git a/packages/web/src/components/organisms/BlogLayout/index.tsx b/packages/web/src/components/organisms/BlogLayout/index.tsx index b748a82..5b19fd6 100644 --- a/packages/web/src/components/organisms/BlogLayout/index.tsx +++ b/packages/web/src/components/organisms/BlogLayout/index.tsx @@ -1,11 +1,18 @@ import * as React from 'react'; import {Layouts, Widgets} from '@tesseract-design/viewfinder-react'; -import Link from 'next/link'; -import * as WebNavigationReact from '@tesseract-design/web-navigation-react'; +import {BlogItem, BlogItemProps} from '@/components/molecules/BlogItem'; -export interface BlogLayoutProps {} +interface SingleBlogItem extends BlogItemProps { + id: string; +} -export const BlogLayout: React.FC = () => ( +export interface BlogLayoutProps { + blogItems: SingleBlogItem[]; +} + +export const BlogLayout: React.FC = ({ + blogItems, +}) => ( @@ -23,41 +30,13 @@ export const BlogLayout: React.FC = () => ( } > -
-
-
-

- Article title -

- -
-
- Excerpt lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. - Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. - Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. - Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. - Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod aliquam. -
-
-
- - Read more - -
-
-
+
+ {blogItems.map((blogItem) => ( + + ))}
diff --git a/packages/web/src/pages/blog/index.tsx b/packages/web/src/pages/blog/index.tsx index fbc4851..d0d6847 100644 --- a/packages/web/src/pages/blog/index.tsx +++ b/packages/web/src/pages/blog/index.tsx @@ -2,14 +2,35 @@ import {NextPage} from 'next'; import {useHuePulsate} from '@/hooks/effects'; import * as config from '@/config'; import {BlogLayout} from '@/components/organisms/BlogLayout'; +import * as Iceform from '@modal-sh/iceform-next'; -const BlogPage: NextPage = () => { +interface BlogPageProps { + data: any; +} + +const BlogPage: Iceform.NextPage = ({ + data, +}) => { useHuePulsate(config.effects.huePulsate); return ( ); }; +export const getServerSideProps = Iceform.destination.getServerSideProps({ + fn: async (actionReq, actionRes, context) => { + const { readFile } = await import('fs/promises'); + const dataJson = await readFile('data.json', 'utf-8'); + const data = JSON.parse(dataJson); + return { + props: { + data, + }, + }; + }, +}); + export default BlogPage; diff --git a/packages/web/src/styles/globals.css b/packages/web/src/styles/globals.css index 71ae42a..4730430 100644 --- a/packages/web/src/styles/globals.css +++ b/packages/web/src/styles/globals.css @@ -465,11 +465,11 @@ a { } h1 { - @apply font-headings lowercase text-5xl font-thin leading-none my-8; + @apply font-headings lowercase text-5xl font-extralight leading-none my-8; } h2 { - @apply font-headings lowercase text-4xl font-thin leading-none my-8; + @apply font-headings lowercase text-4xl font-extralight leading-none my-8; } h3 {