mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
chore: update blog layouts
This commit is contained in:
1 parent
b043ed175e
commit
f5bdc00d24
7 files changed
+175
-86
No files matched your search
@@ -7,10 +7,12 @@ interface Props {
|
||||
|
||||
export default function BlogHeader({ title }: Props) {
|
||||
return (
|
||||
<div className="bg-white dark:bg-dark-800 overflow-hidden py-12 border-b dark:border-gray-600">
|
||||
<div className="container mx-auto px-8 sm:px-16 xl:px-20 mt-16">
|
||||
<div className="mx-auto max-w-7xl">
|
||||
<Typography.Title>{title}</Typography.Title>
|
||||
<div className="bg-white dark:bg-dark-800 overflow-hidden pt-12 pb-4 border-b dark:border-gray-600">
|
||||
<div className="container mx-auto px-8 sm:px-16 xl:px-20">
|
||||
<div className="mx-auto">
|
||||
<Typography.Title>
|
||||
<span className="text-3xl">{title}</span>
|
||||
</Typography.Title>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Badge, Space, Typography } from '@supabase/ui'
|
||||
import authors from 'lib/authors.json'
|
||||
import Link from 'next/link'
|
||||
import React from 'react'
|
||||
import { capitalize } from '~/lib/helpers'
|
||||
import PostTypes from '~/types/post'
|
||||
|
||||
interface Props {
|
||||
@@ -11,62 +12,71 @@ interface Props {
|
||||
const BlogListItem = ({ blog }: Props) => {
|
||||
// @ts-ignore
|
||||
const author = blog.author ? authors[blog.author] : authors['supabase']
|
||||
|
||||
console.log('blog', blog)
|
||||
return (
|
||||
<div key={blog.slug} className="pt-4 pb-12 border-b border-gray-100 dark:border-gray-600 mb-8">
|
||||
<div className="mx-auto max-w-7xl cursor-pointer">
|
||||
<a href={`/blog/${blog.url}`}>
|
||||
<a className="inline-block">
|
||||
<Space direction="vertical" size={5} className="">
|
||||
<div key={blog.slug}>
|
||||
<a href={`/blog/${blog.url}`}>
|
||||
<div className="inline-block">
|
||||
<div className="flex flex-col space-y-3">
|
||||
<img
|
||||
src={
|
||||
!blog.thumb
|
||||
? `https://images.unsplash.com/photo-1569982175971-d92b01cf8694?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1`
|
||||
: `/images/blog/${blog.thumb}`
|
||||
}
|
||||
style={{ minHeight: '220px', maxHeight: '220px', minWidth: '100%' }}
|
||||
className="w-full object-cover border dark:border-dark rounded-sm shadow-sm"
|
||||
/>
|
||||
|
||||
<div>
|
||||
<div className="space-x-3">
|
||||
<Typography.Text type="secondary">{blog.date}</Typography.Text>
|
||||
<Typography.Text type="secondary">•</Typography.Text>
|
||||
<Typography.Text type="secondary">{blog.readingTime}</Typography.Text>
|
||||
</div>
|
||||
<Typography.Title level={4} className="m-0">
|
||||
{blog.title}
|
||||
</Typography.Title>
|
||||
</div>
|
||||
|
||||
{/* {author && (
|
||||
<div>
|
||||
<Space className="mb-2">
|
||||
<Typography.Text type="secondary">{blog.date}</Typography.Text>
|
||||
<Typography.Text type="secondary">•</Typography.Text>
|
||||
<Typography.Text type="secondary">{blog.readingTime}</Typography.Text>
|
||||
</Space>
|
||||
|
||||
<Space direction="vertical" size={3}>
|
||||
<Typography.Title level={3} className="">
|
||||
{blog.title}
|
||||
</Typography.Title>
|
||||
|
||||
<Space className="block">
|
||||
{blog.tags &&
|
||||
blog.tags.map((tag: string) => (
|
||||
<Link href={`/blog/tags/${tag}`} as={`/blog/tags/${tag}`}>
|
||||
<a>
|
||||
<Badge key={`${blog.slug}-${tag}-tag`} dot={false}>
|
||||
{tag}
|
||||
</Badge>
|
||||
</a>
|
||||
</Link>
|
||||
))}
|
||||
<Space size={4}>
|
||||
{author.author_image_url && (
|
||||
<img src={author.author_image_url} className="rounded-full w-8" />
|
||||
)}
|
||||
<Space direction="vertical" size={0}>
|
||||
<Typography.Text>{author.author}</Typography.Text>
|
||||
<Typography.Text type="secondary" small>
|
||||
{author.position}
|
||||
</Typography.Text>
|
||||
</Space>
|
||||
</Space>
|
||||
</div>
|
||||
)} */}
|
||||
</div>
|
||||
<div className="flex space-x-3">
|
||||
{blog.tags &&
|
||||
blog.tags.map((tag: string) => (
|
||||
<Link href={`/blog/tags/${tag}`} as={`/blog/tags/${tag}`}>
|
||||
<div className="transition-opacity opacity-50 hover:opacity-100">
|
||||
<Badge color="gray">{capitalize(tag.replace('-', ' '))}</Badge>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{author && (
|
||||
<div>
|
||||
<Space size={4}>
|
||||
{author.author_image_url && (
|
||||
<img src={author.author_image_url} className="rounded-full w-10" />
|
||||
)}
|
||||
<Space direction="vertical" size={0}>
|
||||
<Typography.Text>{author.author}</Typography.Text>
|
||||
<Typography.Text type="secondary" small>
|
||||
{author.position}
|
||||
</Typography.Text>
|
||||
</Space>
|
||||
</Space>
|
||||
</div>
|
||||
)}
|
||||
{/* <Typography>
|
||||
<Typography.Text className="m-0" type="secondary">
|
||||
{blog.description}
|
||||
</Typography.Text>
|
||||
|
||||
{/* <Typography>
|
||||
<ReactMarkdown>{blog.content.substring(0, 210) + '...'}</ReactMarkdown>
|
||||
</Typography>
|
||||
<Typography.Link>Read more</Typography.Link> */}
|
||||
</Space>
|
||||
</a>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,3 +7,7 @@ export const generateReadingTime = (text: string) => {
|
||||
const readTime = Math.ceil(minutes)
|
||||
return `${readTime} minute read`
|
||||
}
|
||||
|
||||
export function capitalize(word: string) {
|
||||
return word[0].toUpperCase() + word.substring(1).toLowerCase()
|
||||
}
|
||||
+25
-16
@@ -63,19 +63,20 @@ function Blog(props: any) {
|
||||
<NextSeo title="Blog" description="Latest news from the Supabase team." />
|
||||
<DefaultLayout>
|
||||
<BlogHeader title="Blog" />
|
||||
<div className="bg-gray-50 dark:bg-dark-800 overflow-hidden py-12">
|
||||
|
||||
<div className="bg-white dark:bg-dark-800 overflow-hidden py-12">
|
||||
<div className="container mx-auto px-8 sm:px-16 xl:px-20 mt-16">
|
||||
<div className="mx-auto max-w-7xl">
|
||||
<Typography.Title level={2}>Latests posts</Typography.Title>
|
||||
<div className="mt-5 max-w-lg mx-auto grid gap-16 lg:grid-cols-2 lg:max-w-none">
|
||||
{props.blogs.slice(0, 2).map((blog: any, idx: any) => {
|
||||
return FeaturedThumb(blog)
|
||||
})}
|
||||
</div>
|
||||
<div className="mx-auto ">
|
||||
<Typography.Title level={3}>Latests post</Typography.Title>
|
||||
{props.blogs.slice(0, 1).map((blog: any, idx: any) => {
|
||||
return FeaturedThumb(blog)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="border-t dark:border-dark">
|
||||
<div className="container mx-auto px-8 sm:px-16 xl:px-20 mt-32">
|
||||
<div className="mx-auto max-w-7xl">
|
||||
<div className="mx-auto ">
|
||||
<div className="grid grid-cols-12">
|
||||
<div className="col-span-12 lg:col-span-8">
|
||||
<Typography.Title level={2}>More posts from the team</Typography.Title>
|
||||
@@ -100,10 +101,15 @@ function Blog(props: any) {
|
||||
</Space>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-12 max-w-lg mx-auto grid lg:grid-cols-1 lg:max-w-none">
|
||||
</div>
|
||||
|
||||
<div className="">
|
||||
<div className="grid grid-cols-12 mt-16 gap-16">
|
||||
{/* <ul> */}
|
||||
{blogs.map((blog: PostTypes, idx: number) => (
|
||||
<BlogListItem blog={blog} key={idx} />
|
||||
<div className="col-span-3 mb-16">
|
||||
<BlogListItem blog={blog} key={idx} />
|
||||
</div>
|
||||
))}
|
||||
{/* </ul> */}
|
||||
</div>{' '}
|
||||
@@ -120,14 +126,14 @@ function FeaturedThumb(blog: PostTypes) {
|
||||
const author = blog.author ? authors[blog.author] : authors['supabase']
|
||||
|
||||
return (
|
||||
<div key={blog.slug} className="my-6 cursor-pointer">
|
||||
<div key={blog.slug} className="cursor-pointer w-full">
|
||||
<a href={`/blog/${blog.url}`}>
|
||||
<a className="inline-block">
|
||||
<a className="grid grid-cols-2 gap-16">
|
||||
<img
|
||||
className="h-96 w-full object-cover border dark:border-dark"
|
||||
src={`/images/blog/` + (blog.thumb ? blog.thumb : blog.image)}
|
||||
/>
|
||||
<Space direction="vertical" size={5} className="mt-4">
|
||||
<Space direction="vertical" size={5} className="">
|
||||
<div>
|
||||
<Space className="mb-2">
|
||||
<Typography.Text type="secondary">{blog.date}</Typography.Text>
|
||||
@@ -136,16 +142,19 @@ function FeaturedThumb(blog: PostTypes) {
|
||||
</Space>
|
||||
|
||||
<Space direction="vertical" size={3}>
|
||||
<Typography.Title level={3} className="">
|
||||
<Typography.Title level={2} className="m-0">
|
||||
{blog.title}
|
||||
</Typography.Title>
|
||||
<Typography.Text className="m-0" type="secondary">
|
||||
<span className="text-xl">{blog.description}</span>
|
||||
</Typography.Text>
|
||||
|
||||
<Space className="block">
|
||||
{blog.tags &&
|
||||
blog.tags.map((tag: string) => (
|
||||
<a href={`/blog/tags/${tag}`}>
|
||||
<a>
|
||||
<Badge key={`${blog.slug}-${tag}-tag`} dot={false}>
|
||||
<Badge color="gray" key={`${blog.slug}-${tag}-tag`} dot={false}>
|
||||
{tag}
|
||||
</Badge>
|
||||
</a>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Badge, Card, Divider, IconFile, Space, Typography } from '@supabase/ui'
|
||||
import { Badge, Card, Divider, IconChevronLeft, IconFile, Space, Typography } from '@supabase/ui'
|
||||
import matter from 'gray-matter'
|
||||
import authors from 'lib/authors.json'
|
||||
import hydrate from 'next-mdx-remote/hydrate'
|
||||
@@ -176,33 +176,44 @@ function BlogPostPage(props: any) {
|
||||
}}
|
||||
/>
|
||||
<DefaultLayout>
|
||||
<div className="bg-white dark:bg-dark-800 overflow-hidden mb-12">
|
||||
<div className="container px-8 sm:px-16 xl:px-20 lg:mt-16 mx-auto">
|
||||
<div className="max-w-6xl mx-auto">
|
||||
<div className="lg:py-12 grid grid-cols-12 lg:gap-16">
|
||||
<div className="col-span-12 lg:col-span-10">
|
||||
<Link href={`/blog`} as={`/blog`}>
|
||||
<a>
|
||||
<Typography.Text type="secondary">
|
||||
<span className="hover:text-gray-900 dark:hover:text-white cursor-pointer">
|
||||
View more posts
|
||||
</span>
|
||||
</Typography.Text>
|
||||
</a>
|
||||
</Link>
|
||||
<Space className="my-4">
|
||||
<div
|
||||
className="
|
||||
bg-white dark:bg-dark-800
|
||||
container px-8 sm:px-16 xl:px-20 mx-auto
|
||||
py-16
|
||||
"
|
||||
>
|
||||
<div className="grid grid-cols-12 gap-4">
|
||||
<div className="col-span-12 lg:col-span-2">
|
||||
{/* Back button */}
|
||||
<Typography.Text type="secondary">
|
||||
<span className="hover:text-gray-900 dark:hover:text-white cursor-pointer flex items-center">
|
||||
<IconChevronLeft />
|
||||
Back
|
||||
</span>
|
||||
</Typography.Text>
|
||||
</div>
|
||||
<div className="col-span-12 lg:col-span-10">
|
||||
{/* Title and description */}
|
||||
<div className="mb-16 space-y-8 max-w-5xl">
|
||||
<div>
|
||||
<Typography.Text type="success">Blog post</Typography.Text>
|
||||
<Typography.Title>{props.blog.title}</Typography.Title>
|
||||
<div className="flex space-x-3">
|
||||
<Typography.Text>{props.blog.date}</Typography.Text>
|
||||
<Typography.Text type="secondary">•</Typography.Text>
|
||||
<Typography.Text>
|
||||
{generateReadingTime(props.blog.content.renderedOutput)}
|
||||
</Typography.Text>
|
||||
</Space>
|
||||
<Typography.Title>{props.blog.title}</Typography.Title>
|
||||
</div>
|
||||
{author && (
|
||||
<div className="mt-6 mb-8 lg:mb-0">
|
||||
<Space size={4}>
|
||||
{author.author_image_url && (
|
||||
<img src={author.author_image_url} className="rounded-full w-10" />
|
||||
<img
|
||||
src={author.author_image_url}
|
||||
className="rounded-full w-10 border dark:border-dark"
|
||||
/>
|
||||
)}
|
||||
<Space direction="vertical" size={0}>
|
||||
<Typography.Text>{author.author}</Typography.Text>
|
||||
@@ -215,9 +226,60 @@ function BlogPostPage(props: any) {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-12 gap-8">
|
||||
{/* Content */}
|
||||
<div className="col-span-12 lg:col-span-7 xl:col-span-7">
|
||||
{props.blog.thumb && (
|
||||
<img
|
||||
src={'/images/blog/' + props.blog.thumb}
|
||||
className="object-cover mb-8 border dark:border-gray-600"
|
||||
style={{ maxHeight: '520px' }}
|
||||
/>
|
||||
)}
|
||||
<article className={blogStyles['article']}>
|
||||
<Typography>{content}</Typography>
|
||||
</article>
|
||||
</div>
|
||||
{/* Sidebar */}
|
||||
<div className="col-span-12 lg:col-span-5 xl:col-span-3 xl:col-start-9 space-y-8">
|
||||
<div className="hidden lg:block">{toc}</div>
|
||||
<div>
|
||||
<Typography.Title className="mb-4" level={5}>
|
||||
Related articles
|
||||
</Typography.Title>
|
||||
<Space direction="vertical">
|
||||
{props.relatedPosts.map((post: any) => (
|
||||
<Link href={`/blog/${post.url}`} as={`/blog/${post.url}`}>
|
||||
<div>
|
||||
<Typography.Text className="cursor-pointer">
|
||||
<Space>
|
||||
<IconFile size={'small'} style={{ minWidth: '1.2rem' }} />
|
||||
<span className="hover:text-gray-900 dark:hover:text-white">
|
||||
{post.title}
|
||||
</span>
|
||||
</Space>
|
||||
</Typography.Text>
|
||||
<Divider light className="mt-2" />
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
<Link href={`/blog`} as={`/blog`}>
|
||||
<div>
|
||||
<Typography.Text type="secondary">
|
||||
<span className="hover:text-gray-900 dark:hover:text-white cursor-pointer">
|
||||
View all posts
|
||||
</span>
|
||||
</Typography.Text>
|
||||
</div>
|
||||
</Link>
|
||||
</Space>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="container px-8 sm:px-16 xl:px-20 py-16 mx-auto">
|
||||
<div className="max-w-6xl mx-auto">
|
||||
<div className="py-4 grid grid-cols-12 lg:gap-16">
|
||||
|
||||
@@ -169,6 +169,7 @@ function BlogPostPage(props: any) {
|
||||
>
|
||||
<div className="grid grid-cols-12 gap-4">
|
||||
<div className="col-span-12 lg:col-span-2">
|
||||
{/* Back button */}
|
||||
<Typography.Text type="secondary">
|
||||
<span className="hover:text-gray-900 dark:hover:text-white cursor-pointer flex items-center">
|
||||
<IconChevronLeft />
|
||||
|
||||
@@ -14,6 +14,7 @@ type PostTypes = {
|
||||
thumb: string
|
||||
image: string
|
||||
readingTime: string
|
||||
description: string
|
||||
url: string
|
||||
tags: []
|
||||
logo?: string
|
||||
|
||||
Reference in new issue
Block a user