Skip to content

Commit

Permalink
Implement working base structure
Browse files Browse the repository at this point in the history
  • Loading branch information
timolins committed Jul 19, 2020
1 parent d3ef5a9 commit e671583
Show file tree
Hide file tree
Showing 25 changed files with 613 additions and 326 deletions.
4 changes: 4 additions & 0 deletions assets/styles/main.css
Expand Up @@ -20,3 +20,7 @@ button:focus {
@apply border-blue-500 outline-none;
box-shadow: 0 0 0 3px rgba(16, 141, 255, 0.5);
}

.achievement {
padding-left: 0 !important;
}
4 changes: 4 additions & 0 deletions assets/svgs/logo.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
70 changes: 29 additions & 41 deletions components/sections/achievements.tsx
@@ -1,4 +1,4 @@
import React from "react";
import React, { useState } from "react";

import Briefcase from "../../assets/svgs/briefcase.svg";
import Lock from "../../assets/svgs/lock.svg";
Expand All @@ -9,6 +9,7 @@ import { Timestamp } from "../base/timestamp";
import {
Achievement as AchievementProps,
AchievementType,
Achievement,
} from "../../types/achievement";
import { NotionRenderer } from "react-notion";

Expand All @@ -31,40 +32,13 @@ const AchievementIcon: React.FC<{
}
};

// const achievements: AchievementProps[] = [
// {
// type: "award",
// title: "Test",
// date: new Date(),
// Content: () => <div>123213</div>,
// },
// {
// type: "security",
// title: "Test",
// date: new Date(),
// Content: () => <div>test</div>,
// },
// {
// type: "work",
// title: "Test",
// date: new Date(),
// Content: () => <div>test</div>,
// },
// {
// type: "education",
// title: "Test",
// date: new Date(),
// Content: () => <div>test</div>,
// },
// ];

const Achievement: React.FC<AchievementProps> = ({
const AchievementRow: React.FC<AchievementProps> = ({
title,
date,
type,
blockMap,
}) => (
<div className="flex items-center my-8">
<div className="flex items-center my-8 achievement">
<AchievementIcon type={type} />
<h4 className="flex-1 mx-4">
<div className="font-semibold">{title}</div>
Expand All @@ -78,16 +52,30 @@ const Achievement: React.FC<AchievementProps> = ({

export const Achievements: React.FC<{ achievements: Achievement[] }> = ({
achievements,
}) => (
<div className="container">
<div className="mx-32">
<h1 className="text-4xl font-bold">Achievements</h1>
<div className="text-2xl text-gray-600">Things I Have Achieved</div>
<div className="my-4">
{achievements.map((p, i) => (
<Achievement key={i} {...p} />
))}
}) => {
const [showMore, setShowMore] = useState(false);

return (
<div className="container my-16">
<div className="m-auto max-w-4xl">
<h1 className="text-4xl font-bold">Achievements</h1>
<div className="text-2xl text-gray-600">Things I Have Achieved</div>
<div className="my-4">
{achievements
.filter(a => showMore || a.highlight)
.map((a, i) => (
<AchievementRow key={i} {...a} />
))}
</div>
<div className="flex justify-center">
<button
className="px-2 py-1 bg-blue-100 text-blue-700 rounded"
onClick={() => setShowMore(!showMore)}
>
{showMore ? "Show less ↑" : "Show more ↓"}
</button>
</div>
</div>
</div>
</div>
);
);
};
7 changes: 5 additions & 2 deletions components/sections/blog.tsx
Expand Up @@ -3,12 +3,15 @@ import Link from "next/link";

export const Blog: React.FC<{ posts: Post[] }> = ({ posts = [] }) => {
return (
<div className="container">
<div className="container my-8">
<h2 className="text-4xl font-bold">Blog</h2>

{posts.map(post => (
<div>
<div key={post.id}>
<Link href={`/blog/${post.slug}`}>
<a>{post.title}</a>
</Link>
<div className="text-gray-600">{post.preview}</div>
</div>
))}
{/* <CustomHead title="Blog" />
Expand Down
10 changes: 10 additions & 0 deletions components/sections/footer.tsx
@@ -0,0 +1,10 @@
export const Footer: React.FC = () => {
return (
<div className="text-center text-gray-600 text-sm p-4 mt-8">
© {new Date().getFullYear()} Timo Lins ·{" "}
<a className="text-blue-500" href="https://github.com/timolins">
Source
</a>
</div>
);
};
54 changes: 54 additions & 0 deletions components/sections/github-activity.tsx
@@ -0,0 +1,54 @@
import React from "react";

import { Repo } from "../../core/github";
import { config } from "../../config";

const RepoList: React.FC<{
title: string;
url: string;
repos: Repo[];
}> = ({ repos, title, url }) => (
<div>
<h2 className="text-lg text-gray-600 font-semibold">{title}</h2>
<ul>
{repos.map(({ id, name, url, description, owner }) => (
<li
key={id}
className="my-4 py-4 px-4 -mx-4 hover:bg-gray-100 rounded-md"
>
<a href={url}>
<div>
<span className="text-blue-400">{owner.login}/</span>
<span className="text-blue-600">{name}</span>
</div>
<div>{description}</div>
</a>
</li>
))}
</ul>
<a href={url} className="text-blue-600 text-sm">
View more on <span className="font-semibold">GitHub</span>
</a>
</div>
);

export const GitHubActivity: React.FC<{
starredRepos: Repo[];
contributedRepos: Repo[];
}> = ({ starredRepos, contributedRepos }) => (
<div className="container">
<h1 className="text-4xl font-bold">GitHub Activity</h1>
<div className="grid grid-cols-1 md:grid-cols-2 gap-16">
<RepoList
title="Repos I Contributed to"
url={`https://github.com/${config.githubUsername}`}
repos={contributedRepos}
/>
<RepoList
title="Repos I Like"
repos={starredRepos}
url={`https://github.com/${config.githubUsername}?tab=stars`}
/>
</div>
</div>
);
36 changes: 27 additions & 9 deletions components/sections/hero.tsx
@@ -1,10 +1,22 @@
import React from "react";
import Logo from "../../assets/svgs/logo.svg";
import Link from "next/link";

const Nav = () => (
<nav className="flex justify-between items-center my-4">
<div>Logo</div>
<div className="bg-blue-200 text-blue-700 px-2 py-1 rounded-md">
Let's talk
<a href="/">
<Logo className="w-8" />
</a>
<div>
<Link href="/blog">
<a className="text-blue-600 mr-2 px-2 py-1 rounded-md">Blog</a>
</Link>

<Link href="/contact">
<a className="bg-blue-200 text-blue-700 px-2 py-1 rounded-md">
Let's talk
</a>
</Link>
</div>
</nav>
);
Expand All @@ -14,16 +26,22 @@ export const Hero = () => (
<div className="container">
<Nav />

<div className="flex flex-col items-center my-8">
<div className="flex flex-col items-center my-16">
<h1 className="text-4xl font-bold">Hey, I'm Timo!</h1>
<p className="text-2xl text-gray-700">
I'm passionate about JavaScript, Design and Film Making.
</p>
</div>
<div className="text-center grid grid-cols-3 max-w-sm m-auto my-2">
<a href="https://dribbble.com/timolins">Dribbble</a>
<a href="https://github.com/timolins">GitHub</a>
<a href="https://twitter.com/timolins">Twitter</a>
<div className="text-center max-w-sm m-auto my-8">
<a className="mx-2" href="https://dribbble.com/timolins">
Dribbble
</a>
<a className="mx-2" href="https://github.com/timolins">
GitHub
</a>
<a className="mx-2" href="https://twitter.com/timolins">
Twitter
</a>
</div>
</div>
</div>
</section>
Expand Down
103 changes: 101 additions & 2 deletions components/sections/work.tsx
@@ -1,7 +1,106 @@
import React from "react";
import { Project as ProjectData, ProjectType } from "../../types/project";
import { toNotionImageUrl } from "../../core/notion";
import Link from "next/link";

export const Work = () => (
<div className="container">
const TypeBadge: React.FC<{ type: ProjectType }> = ({ type }) => {
const className = "rounded-full px-3 flex items-center text-sm mr-1";
switch (type) {
case "code":
return (
<div className={`${className} bg-green-200 text-green-800`}>Code</div>
);
case "design":
return (
<div className={`${className} bg-orange-200 text-red-700`}>Design</div>
);
case "video":
return (
<div className={`${className} bg-blue-200 text-blue-700`}>Video</div>
);
}
};

const Project: React.FC<
ProjectData & {
featured?: boolean;
}
> = ({ title, preview, images, featured, slug, types }) => (
<div
className={`border rounded-md overflow-hidden flex flex-col ${
featured ? "shadow-sm" : ""
}`}
>
{featured && (
<div className="pb-2/3 bg-gray-100 relative border-b">
{images && images[0] && (
<img
className="absolute w-full h-full object-cover"
src={toNotionImageUrl(images[0].url)}
alt={title}
/>
)}
</div>
)}
<div className="flex flex-1 flex-col justify-between">
<div className="p-4">
<div className="text-xl font-semibold text-gray-800">{title}</div>
<div className="text-gray-600">{preview}</div>
</div>
<div className="flex justify-between p-4">
<div className="flex items-center">
{types.map(type => (
<TypeBadge type={type} />
))}
</div>
<Link href={`/work/${slug}`}>
<a className="border group hover:bg-gray-100 text-blue-900 border-gray-300 py-1 px-3 rounded-md shadow-xs text">
{featured ? "Read more" : "Read"}{" "}
<span className="transform transition-transform duration-300 ease-in-out inline-block text-gray-600 group-hover:translate-x-1">
</span>
</a>
</Link>
</div>
</div>
</div>
);

export const Work: React.FC<{
projects: ProjectData[];
preview?: boolean;
}> = ({ projects, preview }) => (
<div className="container my-8">
<h1 className="text-4xl font-bold">Work</h1>
<div className="text-2xl text-gray-600">Things I Have Made in the Past</div>
<div className="grid grid-cols-3 gap-4">
{projects.slice(0, 3).map(p => (
<Project featured {...p} />
))}
</div>
<div className="grid mt-4 grid-cols-4 gap-4">
{!preview ? (
projects.slice(3).map(p => <Project {...p} />)
) : (
<>
{projects.slice(3, 6).map(p => (
<Project {...p} />
))}
<div className="flex flex-col items-center justify-center text-center">
<div className="text-lg font-bold text-gray-700">
Want to see more?
</div>
<div className="text-gray-600">
Visit the project page to see more.
</div>
<Link href="/work">
<a className="mt-3 bg-gray-800 hover:bg-gray-700 text-gray-100 py-1 px-6 rounded-md">
Explore all
</a>
</Link>
</div>
</>
)}
</div>
</div>
);
8 changes: 8 additions & 0 deletions config.ts
@@ -1,8 +1,16 @@
const githubToken = process.env.GITHUB_TOKEN;

if (!githubToken) {
throw new Error("Missing environment variable GITHUB_TOKEN.");
}

export const config = {
name: "Timo Lins",
subtitle: "Code · Design · Film",
birthday: "1997-09-07",
githubUsername: "timolins",
notionBlogTableId: "3a1f675cc61e47a3b77c858dc66b752a",
notionAchievementTableId: "3e46de9f7eb847e596170b59c16c6fec",
notionProjectTableId: "5e74829f397e430ebf7c18dfacbb7ac0",
githubToken,
};
5 changes: 3 additions & 2 deletions core/blog.ts
@@ -1,17 +1,18 @@
import fetch from "node-fetch";
import { BlockMapType } from "react-notion";

export const getBlogTable = async <T>(blogId: string): Promise<T[]> =>
fetch(`https://notion-api.splitbee.io/v1/table/${blogId}`).then(res =>
res.json()
);

export const getPageBlocks = async (pageId: string) => {
export const getPageBlocks = async (pageId: string): Promise<BlockMapType> => {
return await fetch(
`https://notion-api.splitbee.io/v1/page/${pageId}`
).then(res => res.json());
};

export const getPageViews = async (slug: string) => {
export const getPageViews = async (slug: string): Promise<number> => {
const res = await fetch(
`https://api.splitbee.io/public/timo.sh?path=/blog/${slug}`
).then(res => res.json());
Expand Down

0 comments on commit e671583

Please sign in to comment.