ci: fix build

This commit is contained in:
Morten Olsen
2022-12-07 07:27:49 +01:00
parent 3f5e941446
commit bf5138142d
20 changed files with 441 additions and 84 deletions

View File

@@ -2,8 +2,11 @@
"name": "@morten-olsen/personal-webpage",
"private": true,
"dependencies": {
"@fontsource/black-ops-one": "^4.5.9",
"@fontsource/merriweather": "^4.5.14",
"@fontsource/pacifico": "^4.5.9",
"@fontsource/space-grotesk": "^4.5.10",
"@fontsource/vt323": "^4.5.10",
"@morten-olsen/markdown-loader": "workspace:^",
"@morten-olsen/personal-webpage-articles": "workspace:^",
"@morten-olsen/personal-webpage-profile": "workspace:^",

View File

@@ -0,0 +1,76 @@
import React, { useMemo } from 'react';
import styled from 'styled-components';
import { getArticles } from '@morten-olsen/personal-webpage-articles/dist/index';
import ArticlePreview from '../preview';
import { JumboArticlePreview } from '../preview/jumbo';
import { MiniArticlePreview } from '../preview/mini';
type Props = {
articles: ReturnType<typeof getArticles>;
};
const Wrapper = styled.div`
width: 100%;
`;
const FeaturedArticle = styled.div`
display: flex;
flex-wrap: wrap;
margin: 0 auto;
align-items: center;
justify-content: center;
width: 100%;
`;
const FeaturedArticles = styled.div`
display: flex;
flex-direction: row;
margin: 0 auto;
width: 100%;
flex-wrap: wrap;
`;
const RemainingArticles = styled.div`
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: 0 auto;
width: 100%;
`;
const ArticleGrid: React.FC<Props> = ({ articles }) => {
const sorted = useMemo(
() =>
articles.sort(
(a, b) =>
new Date(b.meta.published).getTime() -
new Date(a.meta.published).getTime()
),
[articles]
);
const featured1 = useMemo(() => sorted.slice(0, 1)[0], [sorted]);
const featured2 = useMemo(() => sorted.slice(1, 4), [sorted]);
const remaining = useMemo(() => sorted.slice(4, 12), [sorted]);
return (
<Wrapper>
<FeaturedArticle>
<JumboArticlePreview article={featured1} />
</FeaturedArticle>
<FeaturedArticles>
{featured2.map((article) => (
<ArticlePreview key={article.title} article={article} />
))}
</FeaturedArticles>
<RemainingArticles>
{remaining.map((article) => (
<MiniArticlePreview key={article.title} article={article} />
))}
</RemainingArticles>
</Wrapper>
);
};
export { ArticleGrid };

View File

@@ -1,30 +1,46 @@
import React from 'react';
import React, { useMemo } from 'react';
import styled from 'styled-components';
import Link from 'next/link';
import { Title1 } from 'typography';
import { getArticles } from '@morten-olsen/personal-webpage-articles/dist/index';
import { createTheme } from 'theme/create';
import { ThemeProvider } from 'theme/provider';
type Props = {
article: ReturnType<typeof getArticles>[number];
};
const Wrapper = styled.div`
height: 300px;
width: 300px;
height: 500px;
border-right: 2px solid rgba(0, 0, 0, 0.1);
flex: 1;
min-width: 200px;
position: relative;
margin: 10px;
margin: 15px;
cursor: pointer;
display: flex;
flex-direction: column;
@media only screen and (max-width: 700px) {
max-height: 300px;
}
`;
const Title = styled(Title1)`
background: ${({ theme }) => theme.colors.primary};
padding: 5px 0;
line-height: 40px;
font-family: 'Black Ops One', sans-serif;
font-size: 25px;
padding: 0 5px;
margin: 5px 0;
`;
const MetaWrapper = styled.div`
position: absolute;
top: 0;
top: 10px;
left: 10px;
right: 10px;
display: flex;
flex-wrap: wrap;
`;
const AsideWrapper = styled.aside<{
@@ -34,7 +50,7 @@ const AsideWrapper = styled.aside<{
background-size: cover;
background-position: center;
${({ image }) => (image ? `background-image: url(${image});` : '')}
position: absolute;
flex: 1;
top: 0;
bottom: 0;
right: 0;
@@ -43,15 +59,26 @@ const AsideWrapper = styled.aside<{
`;
const ArticlePreview: React.FC<Props> = ({ article }) => {
const theme = useMemo(
() =>
createTheme({
baseColor: article.meta.color,
}),
[article.meta.color]
);
return (
<Link href={`/articles/${article.meta.slug}`}>
<Wrapper>
<AsideWrapper image={article.cover!} />
<MetaWrapper>
<Title>{article.title}</Title>
</MetaWrapper>
</Wrapper>
</Link>
<ThemeProvider theme={theme}>
<Link href={`/articles/${article.meta.slug}`}>
<Wrapper>
<AsideWrapper image={article.cover!} />
<MetaWrapper>
{article.title.split(' ').map((word, index) => (
<Title key={index}>{word}</Title>
))}
</MetaWrapper>
</Wrapper>
</Link>
</ThemeProvider>
);
};

View File

@@ -0,0 +1,82 @@
import React from 'react';
import styled from 'styled-components';
import Link from 'next/link';
import { Title1, Body1 } from 'typography';
import { getArticles } from '@morten-olsen/personal-webpage-articles/dist/index';
type Props = {
article: ReturnType<typeof getArticles>[number];
};
const Wrapper = styled.a`
height: 300px;
flex: 1;
position: relative;
margin: 15px;
cursor: pointer;
display: flex;
background: ${({ theme }) => theme.colors.background};
@media only screen and (max-width: 700px) {
flex-direction: column;
height: 500px;
}
`;
const Title = styled(Title1)`
line-height: 40px;
font-family: 'Black Ops One', sans-serif;
font-size: 25px;
padding: 0 5px;
margin: 5px 0;
`;
const Summery = styled(Body1)`
max-width: 300px;
padding: 0 5px;
margin: 5px 0;
overflow: hidden;
letter-spacing: 0.5px;
line-height: 2.1rem;
@media only screen and (max-width: 700px) {
max-height: 100px;
}
`;
const MetaWrapper = styled.div`
display: flex;
flex-direction: column;
padding: 40px;
`;
const AsideWrapper = styled.aside<{
image?: string;
}>`
background: ${({ theme }) => theme.colors.primary};
background-size: cover;
background-position: center;
${({ image }) => (image ? `background-image: url(${image});` : '')}
flex: 1;
top: 0;
bottom: 0;
right: 0;
left: 0;
}
`;
const JumboArticlePreview: React.FC<Props> = ({ article }) => {
return (
<Link href={`/articles/${article.meta.slug}`}>
<Wrapper>
<AsideWrapper image={article.cover!} />
<MetaWrapper>
<Title>{article.title}</Title>
<Summery>{article.content}</Summery>
</MetaWrapper>
</Wrapper>
</Link>
);
};
export { JumboArticlePreview };

View File

@@ -0,0 +1,83 @@
import React, { useMemo } from 'react';
import styled from 'styled-components';
import Link from 'next/link';
import { Title1 } from 'typography';
import { getArticles } from '@morten-olsen/personal-webpage-articles/dist/index';
import { createTheme } from 'theme/create';
import { ThemeProvider } from 'theme/provider';
type Props = {
article: ReturnType<typeof getArticles>[number];
};
const Wrapper = styled.a`
position: relative;
margin: 15px;
cursor: pointer;
display: flex;
width: 220px;
height: 200px;
@media only screen and (max-width: 700px) {
width: 100%;
}
`;
const Title = styled(Title1)`
line-height: 20px;
font-size: 20px;
padding: 5px 5px;
font-family: 'Black Ops One', sans-serif;
margin: 5px 0;
background: ${({ theme }) => theme.colors.background};
`;
const MetaWrapper = styled.div`
display: flex;
flex-direction: row;
flex-wrap: wrap;
padding: 10px;
max-width: 220px;
position: absolute;
`;
const AsideWrapper = styled.aside<{
image?: string;
}>`
background: ${({ theme }) => theme.colors.primary};
background-size: cover;
background-position: center;
${({ image }) => (image ? `background-image: url(${image});` : '')}
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
}
`;
const MiniArticlePreview: React.FC<Props> = ({ article }) => {
const theme = useMemo(
() =>
createTheme({
baseColor: article.meta.color,
}),
[article.meta.color]
);
return (
<ThemeProvider theme={theme}>
<Link href={`/articles/${article.meta.slug}`}>
<Wrapper>
<AsideWrapper image={article.cover!} />
<MetaWrapper>
{article.title.split(' ').map((word, index) => (
<Title key={index}>{word}</Title>
))}
</MetaWrapper>
</Wrapper>
</Link>
</ThemeProvider>
);
};
export { MiniArticlePreview };

View File

@@ -6,7 +6,7 @@ import { ThemeProvider } from 'theme/provider';
const Wrapper = styled.div`
background: ${({ theme }) => theme.colors.background};
color: ${({ theme }) => theme.colors.foreground};
min-height: 90%;
min-height: 100%;
position: relative;
display: flex;
align-items: center;
@@ -14,27 +14,49 @@ const Wrapper = styled.div`
flex-direction: column;
`;
const BackgroundWrapper = styled.div`
const BackgroundWrapper = styled.div<{
image: string;
}>`
position: absolute;
left: 0;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-size: cover;
background-position: center;
opacity: 0.2;
${({ image }) => (image ? `background-image: url(${image});` : '')}
`;
const Content = styled.div`
z-index: 1;
display: flex;
max-width: 1000px;
width: 100%;
align-items: center;
justify-content: center;
flex-direction: column;
`;
type Props = {
backgroundColor: string;
children: ReactNode;
background?: ReactNode;
background?: string;
color?: string;
};
const Sheet: React.FC<Props> = ({ background, children }) => {
const theme = useMemo(() => createTheme({}), []);
const Sheet: React.FC<Props> = ({ color, background, children }) => {
const theme = useMemo(
() =>
createTheme({
baseColor: color,
}),
[color]
);
return (
<ThemeProvider theme={theme}>
<Wrapper>
{background && <BackgroundWrapper>{background}</BackgroundWrapper>}
{children}
<BackgroundWrapper image={background} />
<Content>{children}</Content>
</Wrapper>
</ThemeProvider>
);

View File

@@ -4,6 +4,8 @@ import type { AppProps } from 'next/app';
import Head from 'next/head';
import '@fontsource/merriweather';
import '@fontsource/pacifico';
import '@fontsource/space-grotesk/700.css';
import '@fontsource/black-ops-one';
import { ThemeProvider } from '../theme/provider';
import { createTheme } from '../theme/create';
import chroma from 'chroma-js';
@@ -34,6 +36,7 @@ const GlobalStyle = createGlobalStyle`
a {
text-decoration: none;
font-weight: bold;
}
`;

View File

@@ -1,15 +1,19 @@
import { getArticles } from '@morten-olsen/personal-webpage-articles';
import { GetStaticPaths, GetStaticProps } from 'next';
import styled from 'styled-components';
import React from 'react';
import React, { useMemo } from 'react';
import { ReactMarkdown } from 'react-markdown/lib/react-markdown';
import { Jumbo, Overline } from 'typography';
import { ThemeProvider } from 'theme/provider';
import { createTheme } from 'theme/create';
type Props = {
article: ReturnType<typeof getArticles>[number];
};
const Wrapper = styled.div``;
const Wrapper = styled.div`
background: ${({ theme }) => theme.colors.background};
`;
const ArticleWrapper = styled.article`
margin-right: 40%;
@@ -40,7 +44,6 @@ const ArticleContent = styled.div`
float: left;
padding: 1rem;
margin: 0px 2rem;
font-weight: 100;
margin-left: 0rem;
}
@@ -73,6 +76,7 @@ const ArticleContent = styled.div`
margin: 5px 0;
background: ${({ theme }) => theme.colors.primary};
color: ${({ theme }) => theme.colors.foreground};
font-family: 'Black Ops One', sans-serif;
@media only screen and (max-width: 700px) {
background: transparent;
@@ -92,7 +96,7 @@ const AsideWrapper = styled.aside<{
background: ${({ theme }) => theme.colors.primary};
background-size: cover;
background-position: center;
opacity: 0.5;
opacity: 0.7;
${({ image }) => (image ? `background-image: url(${image});` : '')}
@media only screen and (max-width: 700px) {
@@ -105,16 +109,23 @@ const AsideWrapper = styled.aside<{
`;
const Title = styled(Jumbo)`
font-size: 60px;
line-height: 80px;
font-size: 4rem;
line-height: 4.1rem;
display: inline-block;
background: ${({ theme }) => theme.colors.primary};
color: ${({ theme }) => theme.colors.foreground};
padding: 0 15px;
text-transform: uppercase;
margin: 5px;
font-family: 'Black Ops One', sans-serif;
@media only screen and (max-width: 900px) {
font-size: 2.5rem;
line-height: 3.1rem;
}
@media only screen and (max-width: 700px) {
padding: 5px;
font-size: 2rem;
line-height: 2.1rem;
}
@@ -125,28 +136,37 @@ const Meta = styled(Overline)`
`;
const Article: React.FC<Props> = ({ article }) => {
const theme = useMemo(
() =>
createTheme({
baseColor: article.meta.color,
}),
[article.meta.color]
);
return (
<Wrapper>
<ArticleWrapper>
<ArticleContent>
{article.title.split(' ').map((word, index) => (
<Title key={index}>{word}</Title>
))}
<div>
<Meta>
By Morten Olsen - 5 min read{' '}
{article.pdf && (
<a href={article.pdf} target="_blank">
download as PDF
</a>
)}
</Meta>
</div>
<AsideWrapper image={article.cover} />
<ReactMarkdown>{article.content}</ReactMarkdown>
</ArticleContent>
</ArticleWrapper>
</Wrapper>
<ThemeProvider theme={theme}>
<Wrapper>
<ArticleWrapper>
<ArticleContent>
{article.title.split(' ').map((word, index) => (
<Title key={index}>{word}</Title>
))}
<div>
<Meta>
By Morten Olsen - {article.stats.text}{' '}
{article.pdf && (
<a href={article.pdf} target="_blank">
download as PDF
</a>
)}
</Meta>
</div>
<AsideWrapper image={article.cover} />
<ReactMarkdown>{article.content}</ReactMarkdown>
</ArticleContent>
</ArticleWrapper>
</Wrapper>
</ThemeProvider>
);
};

BIN
webpage/src/pages/cover.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

View File

@@ -5,7 +5,8 @@ import { getArticles } from '@morten-olsen/personal-webpage-articles/dist/index'
import { GetStaticProps } from 'next';
import { getPositions, Position } from '@morten-olsen/personal-webpage-profile';
import { Sheet } from '../components/sheet';
import ArticlePreview from 'components/articles/preview';
import { ArticleGrid } from 'components/articles/grid';
const cover = require('./cover.png');
type Props = {
articles: ReturnType<typeof getArticles>;
@@ -25,29 +26,48 @@ const Title = styled(Jumbo)`
color: ${({ theme }) => theme.colors.foreground};
padding: 0 15px;
text-transform: uppercase;
margin: 5px;
margin: 10px;
font-family: 'Black Ops One', sans-serif;
@media only screen and (max-width: 700px) {
margin: 5px;
font-size: 2rem;
line-height: 2.1rem;
}
`;
const ArticleList = styled.div`
const Arrow = styled.div`
position: absolute;
bottom: 20px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: 0 auto;
align-items: center;
justify-content: center;
:after {
display: flex;
align-items: center;
justify-content: center;
background: ${({ theme }) => theme.colors.primary};
border-radius: 50%;
width: 80px;
height: 80px;
content: '↓';
font-size: 50px;
@media only screen and (max-width: 700px) {
width: 40px;
height: 40px;
}
}
`;
const Index: FC<Props> = ({ articles, positions }) => {
const Index: FC<Props> = ({ articles }) => {
return (
<>
<Sheet backgroundColor="red">
<Sheet color="#c85279" background={cover}>
<Arrow />
<Hero>
{"Hi, I'm Morten Olsen".split(' ').map((char, index) => (
{"Hi, I'm Morten".split(' ').map((char, index) => (
<Title key={index}>{char}</Title>
))}
</Hero>
@@ -57,18 +77,13 @@ const Index: FC<Props> = ({ articles, positions }) => {
))}
</Hero>
</Sheet>
<Sheet backgroundColor="#273c75">
<h2>Articles</h2>
<ArticleList>
{articles.map((article) => (
<ArticlePreview key={article.title} article={article} />
<Sheet color="#ef23e2">
<Hero>
{'Table of Content'.split(' ').map((char, index) => (
<Title key={index}>{char}</Title>
))}
</ArticleList>
</Sheet>
<Sheet backgroundColor="red">
{positions.map((position) => (
<div>{position.attributes.title}</div>
))}
</Hero>
<ArticleGrid articles={articles} />
</Sheet>
</>
);
@@ -77,7 +92,6 @@ const Index: FC<Props> = ({ articles, positions }) => {
export const getStaticProps: GetStaticProps<Props> = async () => {
const articles = getArticles();
const positions = getPositions();
console.log(articles);
return {
props: {
articles,

View File

@@ -17,7 +17,7 @@ const createTheme = (options: CreateOptions = {}) => {
const text = isBright(baseColor) ? BLACK : WHITE;
const bg = isBright(baseColor)
? baseColor.luminance(0.9)
: baseColor.luminance(0.005);
: baseColor.luminance(0.01);
const theme: Theme = {
typography: {
Jumbo: {