feat: classroomio blog v1 (#142)

* style: Improved font size of the answers in the FAQ section of the landing page

* working on the classroomio blog

* there is a bit of a git issue

* changed the footer route

* Merge branch 'main' into issue-139

* Added syntax higlighting,blockquotes styling and image stylings

* restyle and add first blog

* make tagline match home page

* add docs route

---------

Co-authored-by: Rotimi Best <best@classroomio.com>
This commit is contained in:
Em_Dev
2024-02-02 08:18:26 +01:00
committed by GitHub
co-authored by Rotimi Best
parent cadfa81913
commit f828b170b9
32 changed files with 743 additions and 152 deletions
@@ -1,11 +1,17 @@
<script>
import { Footer, Navigation } from '$lib';
import PageTransition from './transition.svelte';
import '../app.css';
export let data;
</script>
<div class="overflow-hidden">
<Navigation />
<slot />
<PageTransition url={data.url}>
<slot />
</PageTransition>
<Footer />
</div>
@@ -0,0 +1,7 @@
export const prerender = true;
export function load({ url }) {
return {
url: url.pathname
};
}
@@ -0,0 +1,31 @@
import { json } from '@sveltejs/kit';
import type { BlogPost } from '$lib/types';
async function getBlogPosts() {
let blogPosts: BlogPost[] = [];
const paths = import.meta.glob('/src/blog/*.md', { eager: true });
for (const path in paths) {
const file = paths[path];
const slug = path.split('/').at(-1)?.replace('.md', '');
if (file && typeof file === 'object' && 'metadata' in file && slug) {
const metadata = file.metadata as Omit<BlogPost, 'slug'>;
const blogPost = { ...metadata, slug } satisfies BlogPost;
blogPost.published && blogPosts.push(blogPost);
}
}
blogPosts = blogPosts.sort(
(first, second) => new Date(second.date).getTime() - new Date(first.date).getTime()
);
return blogPosts;
}
export async function GET() {
const blogPosts = await getBlogPosts();
return json(blogPosts);
}
@@ -0,0 +1,69 @@
<script>
import Chip from '$lib/Chip/Chip.svelte';
import { formatDate } from '$lib/utils/formatDate';
export let data;
</script>
<svelte:head>
<title>Blog | ClassroomIO</title>
</svelte:head>
<div class=" mt-[10%] md:mt-16">
<header class="pt-24 pb-16 w-full flex flex-col items-center text-center">
<h1
class="mx-auto text-3xl md:text-4xl lg:text-6xl font-normal leading-[1.5] text-slate-900 flex flex-col items-center"
>
<span>What's new on</span>
<span class="text-[#1D4EE2] relative"
>ClassroomIO?
<svg
aria-hidden="true"
viewBox="0 0 418 42"
class="absolute right-0 top-3/4 h-[0.58em] fill-indigo-300/70"
preserveAspectRatio="none"
>
<path
d="M203.371.916c-26.013-2.078-76.686 1.963-124.73 9.946L67.3 12.749C35.421 18.062 18.2 21.766 6.004 25.934 1.244 27.561.828 27.778.874 28.61c.07 1.214.828 1.121 9.595-1.176 9.072-2.377 17.15-3.92 39.246-7.496C123.565 7.986 157.869 4.492 195.942 5.046c7.461.108 19.25 1.696 19.17 2.582-.107 1.183-7.874 4.31-25.75 10.366-21.992 7.45-35.43 12.534-36.701 13.884-2.173 2.308-.202 4.407 4.442 4.734 2.654.187 3.263.157 15.593-.78 35.401-2.686 57.944-3.488 88.365-3.143 46.327.526 75.721 2.23 130.788 7.584 19.787 1.924 20.814 1.98 24.557 1.332l.066-.011c1.201-.203 1.53-1.825.399-2.335-2.911-1.31-4.893-1.604-22.048-3.261-57.509-5.556-87.871-7.36-132.059-7.842-23.239-.254-33.617-.116-50.627.674-11.629.54-42.371 2.494-46.696 2.967-2.359.259 8.133-3.625 26.504-9.81 23.239-7.825 27.934-10.149 28.304-14.005.417-4.348-3.529-6-16.878-7.066Z"
/>
</svg>
</span>
</h1>
<p class="w-[90%] md:w-[60%] text-center font-normal text-lg text-slate-700 mt-10 lg:mt-7">
Get the latest news from ClassroomIO, including product updates, team announcements and more!
</p>
</header>
<div class="w-full flex items-center justify-center">
<ul class="flex flex-col items-start justify-start gap-2 w-[90%] md:w-[50%]">
{#each data.posts as post}
<li class=" border-t border-slate-400 py-14 w-full">
<div class="flex md:flex-row flex-col md:items-center gap-2">
<!-- Date -->
<p class="text-sm text-slate-500">{formatDate(post.date)}</p>
<!-- Tags -->
<div class="flex flex-col">
<div class="flex flex-wrap gap-2">
{#each post.tags as tag}
<Chip label={tag} />
{/each}
</div>
</div>
</div>
<a href={`/blog/${post.slug}`} class="group">
<p class="font-bold text-lg py-2 group-hover:text-slate-500">{post.title}</p>
<p class="text-slate-500 py-4">{post.description}</p>
</a>
<div class="flex items-center justify-start gap-4 my-2">
<img src={post.avatar} alt="avatar" class="w-10 h-10 rounded-full" />
<span>
<p class="font-semibold">{post.author}</p>
<p class="text-slate-500">{post.role}</p>
</span>
</div>
</li>
{/each}
</ul>
</div>
</div>
@@ -0,0 +1,7 @@
import type { Post } from '$lib/types';
export async function load({ fetch }) {
const response = await fetch('api/blog');
const posts: Post[] = await response.json();
return { posts };
}
@@ -0,0 +1,63 @@
<script lang="ts">
import Chip from '$lib/Chip/Chip.svelte';
import { formatDate } from '$lib/utils/formatDate';
import { ChevronLeft } from 'carbon-icons-svelte';
export let data;
</script>
<!-- SEO -->
<svelte:head>
<title>{data.meta.title} | ClassroomIO Blog</title>
<meta property="og:type" content="article" />
<meta property="og:title" content={data.meta.title} />
</svelte:head>
<div class=" mt-[10%] md:mt-16">
{#if data}
<article class="py-16">
<!-- Title -->
<hgroup class="flex flex-col items-center justify-center text-center w-full">
<p class="text-sm text-gray-500">{formatDate(data.meta.date)}</p>
<p class="font-bold text-3xl py-2 text-center md:w-[60%]">{data.meta.title}</p>
</hgroup>
<main class="mx-auto max-w-screen-md px-4 lg:px-8">
<div class="flex items-center justify-start gap-4 my-2 border-y border-gray-200 py-4">
<img src={data.meta.avatar} alt="avatar" class="w-10 h-10 rounded-full" />
<span>
<p class="font-semibold">{data.meta.author}</p>
<p class="text-gray-500">{data.meta.role}</p>
</span>
</div>
<!-- Post -->
<div class="prose pt-2 pb-4 border-b border-gray-200">
<svelte:component this={data.content} />
<!-- Tags -->
<div class="flex gap-2 py-4">
{#each data.meta.tags as tag}
<Chip label={tag} />
{/each}
</div>
</div>
<a
href="/blog"
class="flex font-medium items-center gap-2 text-slate-700 text-lg underline my-10"
>
<ChevronLeft class=" w-6 h-6 font-medium" /> Back to all posts
</a>
</main>
</article>
{/if}
</div>
<style>
article {
margin-inline: auto;
}
h1 {
text-transform: capitalize;
}
</style>
@@ -0,0 +1,15 @@
import { error } from '@sveltejs/kit';
export async function load({ params }) {
try {
const blog = await import(`../../../blog/${params.slug}.md`);
return {
content: blog.default,
meta: blog.metadata,
slug: params.slug
};
} catch (e) {
throw error(404, `Could not find ${params.slug}`);
}
}
@@ -0,0 +1 @@
export const prerender = false;
@@ -0,0 +1,17 @@
<script lang="ts">
import { fade } from 'svelte/transition';
export let url: string;
</script>
{#key url}
<div class="transition" in:fade>
<slot />
</div>
{/key}
<style>
.transition {
height: 100%;
}
</style>