Explorar el Código

Extract data

Use a temporary file for data source in the index layout.
master
TheoryOfNekomata hace 1 mes
padre
commit
7cb3253bed
Se han modificado 9 ficheros con 413 adiciones y 164 borrados
  1. +272
    -0
      packages/web/data.json
  2. +0
    -3
      packages/web/src/components/molecules/ContactCtaBanner/index.tsx
  3. +13
    -8
      packages/web/src/components/molecules/MakeSection/index.tsx
  4. +64
    -0
      packages/web/src/components/organisms/BlogLayout/index.tsx
  5. +29
    -30
      packages/web/src/components/organisms/IndexLayout/index.tsx
  6. +0
    -14
      packages/web/src/hooks/contact.ts
  7. +15
    -0
      packages/web/src/pages/blog/index.tsx
  8. +0
    -1
      packages/web/src/pages/contact/index.tsx
  9. +20
    -108
      packages/web/src/pages/index.tsx

+ 272
- 0
packages/web/data.json Ver fichero

@@ -0,0 +1,272 @@
{
"make": [
{
"id": 1,
"url": "http://www.example.com",
"date": "2023-07-03",
"type": "code",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 2,
"url": "http://www.example.com",
"date": "2023-07-03",
"type": "code",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 3,
"url": "http://www.example.com",
"date": "2023-07-03",
"type": "code",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 4,
"url": "http://www.example.com",
"date": "2023-07-03",
"type": "code",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 5,
"url": "http://www.example.com",
"date": "2023-07-03",
"type": "code",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 6,
"url": "http://www.example.com",
"date": "2023-07-03",
"type": "code",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 7,
"url": "http://www.example.com",
"date": "2023-07-03",
"type": "code",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 8,
"url": "http://www.example.com",
"date": "2023-07-03",
"type": "code",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 9,
"url": "http://www.example.com",
"date": "2023-07-03",
"type": "code",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 10,
"url": "http://www.example.com",
"date": "2023-07-03",
"type": "code",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 11,
"url": "http://www.example.com",
"date": "2023-07-03",
"type": "code",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 12,
"url": "http://www.example.com",
"date": "2023-07-03",
"type": "code",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 13,
"url": "http://www.example.com",
"date": "2023-07-03",
"type": "code",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 14,
"url": "http://www.example.com",
"date": "2023-07-03",
"type": "code",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 15,
"url": "http://www.example.com",
"date": "2023-07-03",
"type": "code",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 16,
"url": "http://www.example.com",
"date": "2023-07-03",
"type": "code",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 17,
"url": "http://www.example.com",
"date": "2023-07-03",
"type": "code",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 18,
"url": "http://www.example.com",
"date": "2023-07-03",
"type": "code",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 19,
"url": "http://www.example.com",
"date": "2023-07-03",
"type": "code",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 20,
"url": "http://www.example.com",
"date": "2023-07-03",
"type": "code",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
}
],
"envision": [
{
"id": 1,
"url": "http://www.example.com",
"imageUrl": "http://placehold.it/1",
"title": "Lorem ipsum dolor sit amet",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 2,
"url": "http://www.example.com",
"imageUrl": "http://placehold.it/1",
"title": "Lorem ipsum dolor sit amet",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 3,
"url": "http://www.example.com",
"imageUrl": "http://placehold.it/1",
"title": "Lorem ipsum dolor sit amet",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 4,
"url": "http://www.example.com",
"imageUrl": "http://placehold.it/1",
"title": "Lorem ipsum dolor sit amet",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 5,
"url": "http://www.example.com",
"imageUrl": "http://placehold.it/1",
"title": "Lorem ipsum dolor sit amet",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
},
{
"id": 6,
"url": "http://www.example.com",
"imageUrl": "http://placehold.it/1",
"title": "Lorem ipsum dolor sit amet",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum."
}
],
"featured": [
{
"title": "yasumi",
"description": "HATEOAS-first, resource-based backend framework in Node.",
"links": [
{
"href": "https://code.modal.sh/modal-soft/yasumi",
"children": "Explore Code",
"primary": true
}
],
"showcase": {
"type": "img",
"src": "/images/a96d02d8cc43cc3b9f1e77c43dfa5644.png"
}
},
{
"title": "formxtra",
"description": "Extract and set form values through the DOM—no frameworks required!",
"links": [
{
"href": "https://codepen.io/theoryofnekomata/pen/xxajmvJ",
"children": "View Demo"
},
{
"href": "https://code.modal.sh/TheoryOfNekomata/formxtra",
"children": "Explore Code",
"primary": true
}
],
"showcase": {
"type": "iframe",
"allowFullScreen": true,
"src": "https://codepen.io/theoryofnekomata/embed/xxajmvJ?default-tab=result&theme-id=dark",
"sandbox": "allow-forms allow-modals allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-top-navigation-by-user-activation allow-downloads allow-presentation",
"allow": "accelerometer; camera; encrypted-media; display-capture; geolocation; gyroscope; microphone; midi; clipboard-read; clipboard-write; web-share"
}
},
{
"title": "tesseract",
"description": "Functional, accessible, aesthetic design system.",
"links": [
{
"href": "https://code.modal.sh/tesseract-design/tesseract",
"children": "Explore Code",
"primary": true
}
],
"showcase": {
"type": "img",
"src": "/images/162cab44da8420c50900d8f11c6da6fd.jpg"
}
},
{
"title": "numerica",
"description": "Gets the name of a number, even if it's stupidly big.",
"links": [
{
"href": "https://code.modal.sh/modal-soft/numerica",
"children": "Explore Code",
"primary": true
}
],
"showcase": {
"type": "img",
"src": "/images/d69ab7f4e5747b5b8f297e4ebe9770f5.png"
}
},
{
"title": "webvideo-transcript-summarizer",
"description": "Get transcript summaries of Web videos. Powered by OpenAI.",
"links": [
{
"href": "https://code.modal.sh/modal-soft/webvideo-transcript-summary",
"children": "Explore Code",
"primary": true
}
],
"showcase": {
"type": "img",
"src": "/images/3cd237361eada7fd30eb96d42d55ec00.jpg"
}
}
]
}

+ 0
- 3
packages/web/src/components/molecules/ContactCtaBanner/index.tsx Ver fichero

@@ -8,14 +8,12 @@ import * as WebActionReact from '@tesseract-design/web-action-react';
import {Brand} from '@/components/molecules/Brand';

export interface ContactCtaBannerProps {
onSubmit?: React.FormEventHandler<HTMLFormElement>;
visible?: boolean;
hasBrand?: boolean;
iceformProps?: Partial<ReturnType<typeof Iceform.useResponse>>;
}

export const ContactCtaBanner: React.FC<ContactCtaBannerProps> = ({
onSubmit,
visible: visibleProp = false,
hasBrand = false,
iceformProps = {},
@@ -83,7 +81,6 @@ export const ContactCtaBanner: React.FC<ContactCtaBannerProps> = ({
{...iceformProps}
className="mt-8"
aria-label="Contact Form"
onSubmit={onSubmit}
method="post"
action="/a/contact"
clientAction="/api/contact"


+ 13
- 8
packages/web/src/components/molecules/MakeSection/index.tsx Ver fichero

@@ -18,13 +18,18 @@ export const MakeSection: React.FC<MakeSectionProps> = ({
data,
}) => {
const groupedData = data.reduce(
(grouped, datum) => ({
...grouped,
[datum.date.getFullYear()]: [
...(grouped[datum.date.getFullYear()] ?? []),
datum,
],
}),
(grouped, datum) => {
const year = new Date(datum.date).getFullYear();
return {
...grouped,
[year]: [
...(
grouped[year] ?? []
),
datum,
],
};
},
{} as Record<string, MakeSectionDatum[]>,
);

@@ -86,7 +91,7 @@ export const MakeSection: React.FC<MakeSectionProps> = ({
key={id}
>
<a href="#" className="block">
<FeedItem {...datum} />
<FeedItem {...datum} date={new Date(datum.date)} />
</a>
</div>
))}


+ 64
- 0
packages/web/src/components/organisms/BlogLayout/index.tsx Ver fichero

@@ -0,0 +1,64 @@
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';

export interface BlogLayoutProps {}

export const BlogLayout: React.FC<BlogLayoutProps> = () => (
<Layouts.LeftSidebar.Root
sidebarBaseWidget={
<Widgets.LeftSidebarBase>
<Layouts.LeftSidebar.SidebarContentContainer>
<aside className="my-16">
<h1 className="m-0">
Sidebar
</h1>
<div>
afasdfs
</div>
</aside>
</Layouts.LeftSidebar.SidebarContentContainer>
</Widgets.LeftSidebarBase>
}
>
<Layouts.LeftSidebar.MainContentContainer>
<main className="my-16 flex gap-8">
<article
className="rounded overflow-hidden relative flex flex-col gap-4 before:absolute before:top-0 before:left-0 before:w-full before:h-full before:border-2 before:rounded-inherit px-4 py-3 before:pointer-events-none before:opacity-10"
>
<header>
<h1 className="m-0">
Article title
</h1>
<time className="font-headings lowercase font-extralight text-3xl">
2024 March 5 23:58
</time>
</header>
<div>
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.
</div>
<footer className="flex justify-end">
<div className="w-48">
<WebNavigationReact.LinkButton
component={Link as unknown as 'a'}
href={{
pathname: '/feed',
} as unknown as string}
menuItem
block
subtext="Article Title"
>
Read more
</WebNavigationReact.LinkButton>
</div>
</footer>
</article>
</main>
</Layouts.LeftSidebar.MainContentContainer>
</Layouts.LeftSidebar.Root>
);

+ 29
- 30
packages/web/src/components/organisms/IndexLayout/index.tsx Ver fichero

@@ -14,7 +14,6 @@ export interface IndexLayoutProps {
makeSectionData?: MakeSectionProps['data'];
envisionSectionData?: EnvisionSectionProps['data'];
featuredProjectData?: FeaturedProjectSectionProps[];
onSubmit?: React.FormEventHandler<HTMLFormElement>;
contactVisible?: boolean;
hasMainLandingSection?: boolean;
contactHasBrand?: boolean;
@@ -26,7 +25,6 @@ export const IndexLayout: React.FC<IndexLayoutProps> = ({
makeSectionData,
envisionSectionData,
featuredProjectData = [],
onSubmit,
contactVisible = false,
hasMainLandingSection = false,
contactHasBrand = false,
@@ -40,36 +38,37 @@ export const IndexLayout: React.FC<IndexLayoutProps> = ({
<BackgroundGrid images={backgroundImages} />
</div>
</div>
{hasMainLandingSection && (
<>
<MainLandingSection
backgroundImages={backgroundImages}
<main className="contents">
{hasMainLandingSection && (
<>
<MainLandingSection
backgroundImages={backgroundImages}
/>
<div id="start" />
</>
)}
{Array.isArray(makeSectionData) && (
<MakeSection
data={makeSectionData}
/>
<div id="start" />
</>
)}
{Array.isArray(makeSectionData) && (
<MakeSection
data={makeSectionData}
/>
)}
{Array.isArray(envisionSectionData) && (
<EnvisionSection
data={envisionSectionData}
/>
)}
{featuredProjectData.map((featuredProjectProps) => (
<FeaturedProjectSection
key={featuredProjectProps.title}
{...featuredProjectProps}
)}
{Array.isArray(envisionSectionData) && (
<EnvisionSection
data={envisionSectionData}
/>
)}
{featuredProjectData.map((featuredProjectProps) => (
<FeaturedProjectSection
key={featuredProjectProps.title}
{...featuredProjectProps}
/>
))}
<ContactCtaBanner
visible={contactVisible}
hasBrand={contactHasBrand}
iceformProps={iceformProps}
/>
))}
<ContactCtaBanner
onSubmit={onSubmit}
visible={contactVisible}
hasBrand={contactHasBrand}
iceformProps={iceformProps}
/>
</main>
<Footer/>
</Layouts.Basic.Root>
);

+ 0
- 14
packages/web/src/hooks/contact.ts Ver fichero

@@ -1,14 +0,0 @@
import * as React from 'react';
import { getFormValues } from '@theoryofnekomata/formxtra';

export const useContactForm = () => {
const processContactForm: React.FormEventHandler<HTMLFormElement> = (e) => {
e.preventDefault();
const values = getFormValues(e.currentTarget);
console.log(values);
};

return React.useMemo(() => ({
processContactForm
}), []);
};

+ 15
- 0
packages/web/src/pages/blog/index.tsx Ver fichero

@@ -0,0 +1,15 @@
import {NextPage} from 'next';
import {useHuePulsate} from '@/hooks/effects';
import * as config from '@/config';
import {BlogLayout} from '@/components/organisms/BlogLayout';

const BlogPage: NextPage = () => {
useHuePulsate(config.effects.huePulsate);

return (
<BlogLayout
/>
);
};

export default BlogPage;

+ 0
- 1
packages/web/src/pages/contact/index.tsx Ver fichero

@@ -21,7 +21,6 @@ const IMAGE_CHOICES = [
];

const ContactPage: Iceform.NextPage = ({
req,
res,
}) => {
const {


+ 20
- 108
packages/web/src/pages/index.tsx Ver fichero

@@ -1,7 +1,5 @@
import type { NextPage } from 'next';
import * as React from 'react';
import {useHuePulsate} from '@/hooks/effects';
import {useContactForm} from '@/hooks/contact';
import {IndexLayout} from '@/components/organisms/IndexLayout';
import * as config from '@/config';
import * as Iceform from '@modal-sh/iceform-next';
@@ -22,110 +20,13 @@ const IMAGE_CHOICES = [
'/images/fe3050a31d3fb86accf26cc4bebec102.png',
];

const makeSectionData = new Array(20).fill(null).map((_, index) => ({
id: (index + 1).toString(),
url: 'http://www.example.com',
date: new Date('2023-07-03'),
type: 'code',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum.',
}));
export interface IndexPageProps {
data: any;
}

const envisionSectionData = new Array(6).fill(null).map((_, index) => ({
id: (index + 1).toString(),
url: 'http://www.example.com',
imageUrl: 'http://placehold.it/1',
title: 'Lorem ipsum dolor sit amet',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae diam eget nunc aliquam vestibulum. Sed vitae diam eget nunc aliquam vestibulum.',
}));

const featuredProjectData = [
{
title: 'yasumi',
description: 'HATEOAS-first, resource-based backend framework in Node.',
links:[
{
href: 'https://code.modal.sh/modal-soft/yasumi',
children: 'Explore Code',
primary: true,
},
],
showcase: {
type: 'img' as const,
src: '/images/a96d02d8cc43cc3b9f1e77c43dfa5644.png',
},
},
{
title: 'formxtra',
description: "Extract and set form values through the DOM—no frameworks required!",
links:[
{
href: 'https://codepen.io/theoryofnekomata/pen/xxajmvJ',
children: 'View Demo',
},
{
href: 'https://code.modal.sh/TheoryOfNekomata/formxtra',
children: 'Explore Code',
primary: true,
},
],
showcase: {
type: 'iframe' as const,
allowFullScreen: true,
src: 'https://codepen.io/theoryofnekomata/embed/xxajmvJ?default-tab=result&theme-id=dark',
sandbox: 'allow-forms allow-modals allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-top-navigation-by-user-activation allow-downloads allow-presentation',
allow: 'accelerometer; camera; encrypted-media; display-capture; geolocation; gyroscope; microphone; midi; clipboard-read; clipboard-write; web-share',
},
},
{
title: 'tesseract',
description: 'Functional, accessible, aesthetic design system.',
links:[
{
href: 'https://code.modal.sh/tesseract-design/tesseract',
children: 'Explore Code',
primary: true,
},
],
showcase: {
type: 'img' as const,
src: '/images/162cab44da8420c50900d8f11c6da6fd.jpg',
},
},
{
title: 'numerica',
description: 'Gets the name of a number, even if it\'s stupidly big.',
links:[
{
href: 'https://code.modal.sh/modal-soft/numerica',
children: 'Explore Code',
primary: true,
},
],
showcase: {
type: 'img' as const,
src: '/images/d69ab7f4e5747b5b8f297e4ebe9770f5.png',
},
},
{
title: 'webvideo-transcript-summarizer',
description: 'Get transcript summaries of Web videos. Powered by OpenAI.',
links:[
{
href: 'https://code.modal.sh/modal-soft/webvideo-transcript-summary',
children: 'Explore Code',
primary: true,
},
],
showcase: {
type: 'img' as const,
src: '/images/3cd237361eada7fd30eb96d42d55ec00.jpg',
},
},
];

const IndexPage: Iceform.NextPage = ({
req,
const IndexPage: Iceform.NextPage<IndexPageProps> = ({
res,
data,
}) => {
const {
response,
@@ -139,15 +40,26 @@ const IndexPage: Iceform.NextPage = ({
return (
<IndexLayout
backgroundImages={IMAGE_CHOICES}
makeSectionData={makeSectionData}
envisionSectionData={envisionSectionData}
featuredProjectData={featuredProjectData}
makeSectionData={data.make}
envisionSectionData={data.envision}
featuredProjectData={data.featured}
hasMainLandingSection
iceformProps={iceformProps}
/>
);
};

export const getServerSideProps = Iceform.destination.getServerSideProps();
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 IndexPage;

Cargando…
Cancelar
Guardar