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 <[email protected]>
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
+7 -2
View File
@@ -8,7 +8,7 @@
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch",
"prepare": "svelte-kit sync"
"prepare": "svelte-kit sync"
},
"devDependencies": {
"@melt-ui/pp": "^0.1.2",
@@ -17,6 +17,7 @@
"@sveltejs/kit": "^1.20.4",
"autoprefixer": "^10.4.15",
"carbon-icons-svelte": "^12.3.0",
"mdsvex": "^0.11.0",
"postcss": "^8.4.29",
"svelte": "^4.0.5",
"svelte-check": "^3.4.3",
@@ -27,6 +28,10 @@
},
"type": "module",
"dependencies": {
"posthog-node": "^3.1.3"
"posthog-node": "^3.1.3",
"rehype-slug": "^6.0.0",
"remark-toc": "^9.0.0",
"remark-unwrap-images": "^4.0.0",
"shiki": "^0.14.7"
}
}
+59 -4
View File
@@ -14,10 +14,6 @@ li {
font-family: 'Inter', sans-serif;
}
.inter {
font-family: 'Inter', sans-serif;
}
.floating {
-webkit-animation: floating 2.5s linear infinite;
animation: floating 2.5s linear infinite;
@@ -46,3 +42,62 @@ li {
transform: translateY(1rem);
}
}
.prose {
font-family: 'Inter', sans-serif;
}
.prose :is(h1, h2, h3, h4, h5, h6) {
font-weight: 700;
margin-top: 8px;
}
.prose :is(h1) {
font-size: 2em;
}
.prose :is(h2) {
font-size: 1.5em;
}
.prose :is(h3) {
font-size: 1.17em;
}
.prose :is(h4) {
font-size: 1em;
}
.prose :is(h5) {
font-size: 0.83em;
}
.prose :is(h6) {
font-size: 0.67em;
}
.prose :is(p, li) {
margin-top: 1.25em;
margin-bottom: 1.25em;
color: #374151;
}
.prose :is(ul, ol) {
list-style-type: disc;
padding-left: 3rem;
}
.prose pre {
max-inline-size: 100%;
padding: 1rem;
border-radius: 8px;
tab-size: 2;
}
.prose blockquote {
border-left: 4px solid gray;
font-style: italic;
font-weight: 500;
padding-left: 16px;
margin: 20px 0;
}
.prose figure + em {
display: block;
font-size: 14px;
margin-bottom: 40px;
border: none;
padding: none;
text-align: center;
}
+121 -53
View File
@@ -1,62 +1,130 @@
<!DOCTYPE html>
<html lang="en">
<!doctype html>
<html lang="en" class="scroll-smooth">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<meta name="theme-color" content="#333333" />
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<meta name="theme-color" content="#333333" />
<title>ClassroomIO –&nbsp;Launch Your Online Bootcamp In Minutes</title>
<meta name="description" content="ClassroomIO" />
<meta name="application-name" content="ClassroomIO" />
<meta name="apple-mobile-web-app-title" content="ClassroomIO" />
<meta name="theme-color" content="#ffffff" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>ClassroomIO –&nbsp;Launch Your Online Bootcamp In Minutes</title>
<meta name="description" content="ClassroomIO" />
<meta name="application-name" content="ClassroomIO">
<meta name="apple-mobile-web-app-title" content="ClassroomIO">
<meta name="theme-color" content="#ffffff" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- Facebook Meta Tags -->
<meta property="og:url" content="https://www.classroomio.com/" />
<meta
property="og:image"
itemprop="image"
content="https://classroomio.com/classroomio-opengraph-image.png"
/>
<meta property="og:title" content="ClassroomIO –&nbsp;Launch Your Online Bootcamp In Minutes" />
<meta
property="og:description"
content="ClassroomIO is a no-code tool that allows you build and scale your own teaching platform with ease."
/>
<!-- Facebook Meta Tags -->
<meta property="og:url" content="https://www.classroomio.com/">
<meta property="og:image" itemprop="image" content="https://classroomio.com/classroomio-opengraph-image.png">
<meta property="og:title" content="ClassroomIO –&nbsp;Launch Your Online Bootcamp In Minutes" />
<meta property="og:description"
content="ClassroomIO is a no-code tool that allows you build and scale your own teaching platform with ease." />
<meta property="og:type" content="website" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="1920" />
<meta property="og:image:height" content="1080" />
<meta
property="og:image:secure_url"
itemprop="image"
content="https://classroomio.com/classroomio-opengraph-image.png"
/>
<meta name="twitter:card" content="summary_large_image" />
<meta property="twitter:domain" content="classroomio.com" />
<meta property="twitter:url" content="https://www.classroomio.com/" />
<meta
name="twitter:title"
content="ClassroomIO – The Open Source Platform for Tech Bootcamps"
/>
<meta
name="twitter:description"
content="Spend less time doing the boring stuff, instead focus on impacting the lives of your students."
/>
<meta name="twitter:image" content="https://classroomio.com/classroomio-opengraph-image.png" />
<!-- <link rel="stylesheet" href="global.css"> -->
<link rel="manifest" href="/manifest.json" crossorigin="use-credentials" />
<link rel="icon" type="image/png" href="/favicon.ico" />
<link rel="icon" type="image/png" sizes="32x32" href="/logo-32.png" />
<meta name="twitter:card" content="summary_large_image" />
<meta property="twitter:domain" content="classroomio.com" />
<meta property="twitter:url" content="https://www.classroomio.com/" />
<meta name="twitter:title" content="ClassroomIO – Launch Your Online Bootcamp In Minutes" />
<meta
name="twitter:description"
content="ClassroomIO is a no-code tool that allows you build and scale your own teaching platform with ease."
/>
<meta name="twitter:image" content="https://classroomio.com/classroomio-opengraph-image.png" />
<!-- <link rel="stylesheet" href="global.css"> -->
<link rel="manifest" href="/manifest.json" crossorigin="use-credentials" />
<link rel="icon" type="image/png" href="/favicon.ico" />
<link rel="icon" type="image/png" sizes="32x32" href="/logo-32.png" />
<meta property="og:type" content="website" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="1920" />
<meta property="og:image:height" content="1080" />
<meta property="og:image:secure_url" itemprop="image"
content="https://classroomio.com/classroomio-opengraph-image.png" />
<script
async
src="https://analytics.umami.is/script.js"
data-website-id="efd70f1f-1f2e-4513-a1dd-ba7826fec138"
></script>
<meta name="twitter:card" content="summary_large_image">
<meta property="twitter:domain" content="classroomio.com">
<meta property="twitter:url" content="https://www.classroomio.com/">
<meta name="twitter:title" content="ClassroomIO – Launch Your Online Bootcamp In Minutes">
<meta name="twitter:description"
content="ClassroomIO is a no-code tool that allows you build and scale your own teaching platform with ease.">
<meta name="twitter:image" content="https://classroomio.com/classroomio-opengraph-image.png">
<!-- <link rel="stylesheet" href="global.css"> -->
<link rel="manifest" href="/manifest.json" crossorigin="use-credentials" />
<link rel="icon" type="image/png" href="/favicon.ico" />
<link rel="icon" type="image/png" sizes="32x32" href="/logo-32.png" />
<script type="text/javascript">
window.$crisp = [];
window.CRISP_WEBSITE_ID = '69176b47-5f63-42cc-bb9b-68d4927b6276';
(function () {
d = document;
s = d.createElement('script');
s.src = 'https://client.crisp.chat/l.js';
s.async = 1;
d.getElementsByTagName('head')[0].appendChild(s);
})();
</script>
<script async src="https://analytics.umami.is/script.js"
data-website-id="efd70f1f-1f2e-4513-a1dd-ba7826fec138"></script>
<script type="text/javascript">
(function (C, A, L) {
let p = function (a, ar) {
a.q.push(ar);
};
let d = C.document;
C.Cal =
C.Cal ||
function () {
let cal = C.Cal;
let ar = arguments;
if (!cal.loaded) {
cal.ns = {};
cal.q = cal.q || [];
d.head.appendChild(d.createElement('script')).src = A;
cal.loaded = true;
}
if (ar[0] === L) {
const api = function () {
p(api, arguments);
};
const namespace = ar[1];
api.q = api.q || [];
typeof namespace === 'string' ? (cal.ns[namespace] = api) && p(api, ar) : p(cal, ar);
return;
}
p(cal, ar);
};
})(window, 'https://app.cal.com/embed/embed.js', 'init');
Cal('init', { origin: 'https://cal.com' });
<script
type="text/javascript">window.$crisp = []; window.CRISP_WEBSITE_ID = "69176b47-5f63-42cc-bb9b-68d4927b6276"; (function () { d = document; s = d.createElement("script"); s.src = "https://client.crisp.chat/l.js"; s.async = 1; d.getElementsByTagName("head")[0].appendChild(s); })();</script>
Cal('ui', {
theme: 'light',
styles: { branding: { brandColor: '#1D4EE2' } },
hideEventTypeDetails: false,
layout: 'month_view'
});
</script>
%sveltekit.head%
</head>
<script type="text/javascript">
(function (C, A, L) { let p = function (a, ar) { a.q.push(ar); }; let d = C.document; C.Cal = C.Cal || function () { let cal = C.Cal; let ar = arguments; if (!cal.loaded) { cal.ns = {}; cal.q = cal.q || []; d.head.appendChild(d.createElement("script")).src = A; cal.loaded = true; } if (ar[0] === L) { const api = function () { p(api, arguments); }; const namespace = ar[1]; api.q = api.q || []; typeof namespace === "string" ? (cal.ns[namespace] = api) && p(api, ar) : p(cal, ar); return; } p(cal, ar); }; })(window, "https://app.cal.com/embed/embed.js", "init");
Cal("init", { origin: "https://cal.com" });
Cal("ui", { "theme": "light", "styles": { "branding": { "brandColor": "#1D4EE2" } }, "hideEventTypeDetails": false, "layout": "month_view" });
</script>
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>
@@ -0,0 +1,33 @@
---
title: 'Teach with Data and Analytics'
description: 'Insights to how students are picking up the concepts you teach are very crucial and we think you should track that metric to enhance your students learning outcome.'
date: '2024-01-02'
author: Rotimi Best
avatar: /blog/best.jpg
role: Founder
tags: ['Analytics', 'Educators']
published: true
---
![best](/blog/analytics-classroom-by-dalle3-classroomio.jpeg)
_Analytics Driven Classroom generated by DALL.E 3_
In the pursuit of educational excellence, it's paramount that teachers comprehend the level of their students' understanding immediately after a lesson. The gap between teaching and assessing student understanding can often widen, leaving educators in the dark until formal testing occurs. Enter ClassroomIO, a revolutionary platform tailored for educators who are ready to bridge this gap with the power of analytics and AI.
With ClassroomIO, the post-lesson period becomes a goldmine of insights. By converting lesson notes into quizzes directly on our platform, teachers can assess understanding without delay. As students submit quiz responses, ClassroomIO works its magic, offering in-depth analytics that reveals the distribution of answers and pinpoints common misconceptions.
## Strategic Intervention for Misunderstood Concepts
Imagine knowing, at a glance, what percentage of your class misunderstood a critical concept from yesterday's lesson. ClassroomIO makes this possible. Such timely feedback allows for swift intervention, ensuring that no student is left behind as the curriculum advances. Teachers can readdress topics with precision, fostering a responsive learning environment.
## Tailored Support for Every Student
Beyond class-wide trends, ClassroomIO's analytics enable personalized student support. With data revealing individual struggles, teachers can recommend targeted learning materials to students requiring additional aid. This individualized approach not only supports students but also frees up valuable teacher time.
## The Future is Here
ClassroomIO isn't just about quizzes and data; it's about empowering educators to make informed decisions that elevate their teaching and enrich student learning. As we harness the power of AI to streamline the educational process, teachers can focus on what they do best — inspiring and instructing the minds of tomorrow.
## Join the Movement
We invite you to be part of the change. Whether you're a classroom teacher, school principal, or online educator, [ClassroomIO](https://classroomio.com) is your partner in crafting the future of education. Embrace the shift to a data-informed teaching approach with [ClassroomIO](https://classroomio.com) — where every lesson becomes an opportunity for growth, for you and your students.
+6 -10
View File
@@ -48,27 +48,23 @@
>
<div class="w-full">
<h2
class="w-full order-first text-3xl font-semibold inter tracking-tight text-gray-900 sm:text-5xl"
class="w-full order-first text-3xl font-semibold tracking-tight text-gray-900 sm:text-5xl"
>
1 thousand
</h2>
<p class="text-base leading-7 text-gray-600 inter">Feedback collected</p>
<p class="text-base leading-7 text-gray-600">Feedback collected</p>
</div>
<div class="w-full">
<h2
class="order-first text-3xl font-semibold tracking-tight text-gray-900 sm:text-5xl inter"
>
<h2 class="order-first text-3xl font-semibold tracking-tight text-gray-900 sm:text-5xl">
5 thousand
</h2>
<p class="text-base leading-7 text-gray-600 inter">Documents processed</p>
<p class="text-base leading-7 text-gray-600">Documents processed</p>
</div>
<div class="w-full">
<h2
class="order-first text-3xl font-semibold tracking-tight text-gray-900 sm:text-5xl inter"
>
<h2 class="order-first text-3xl font-semibold tracking-tight text-gray-900 sm:text-5xl">
1 million
</h2>
<p class="text-base leading-7 text-gray-600 inter">Page views recorded</p>
<p class="text-base leading-7 text-gray-600">Page views recorded</p>
</div>
</div>
{/if}
@@ -0,0 +1,7 @@
<script lang="ts">
export let label: string;
</script>
<p class="whitespace-nowrap bg-gray-200 px-2 py-1 rounded-full text-xs font-normal text-black">
{label}
</p>
+5 -5
View File
@@ -8,7 +8,7 @@
Questions & Answers
</h1>
<h3
class="lg:px-[20%] mt-4 text-lg lg:text-xl text-gray-500 inter font-normal tracking-normal lg:tracking-wide"
class="lg:px-[20%] mt-4 text-lg lg:text-xl text-gray-500 font-normal tracking-normal lg:tracking-wide"
>
Can’t find the answer you’re looking for?
<a class="text-[#1D4EE2]" href="mailto:[email protected]" target="_blank"
@@ -20,11 +20,11 @@
<div class="grid grid-cols-1 lg:grid-cols-3 gap-10 lg:gap-20 lg:px-[13%] mt-[20%] lg:m-0">
{#each faqs as faq}
<div class="max-w-[100%] px-6 lg:p-0">
<h1 class="text:md lg:text-md font-semibold leading-8 text-gray-800 inter">
<h1 class="text:md lg:text-md font-semibold leading-8 text-gray-800">
{faq.question}
</h1>
<p
class="mt-2 text:md lg:text-md font-light leading-7 lg:leading-9 text-gray-600 inter tracking-wide"
class="mt-2 text:md lg:text-md font-light leading-7 lg:leading-9 text-gray-600 tracking-wide"
>
{faq.answer}
</p>
@@ -38,11 +38,11 @@
<h1 class="mt-3 lg:mt-2 text-3xl lg:text-4xl font-bold font-display tracking-tight text-white">
Supercharge your Classroom Today
</h1>
<p class="mt-6 text-xl lg:text-lg text-gray-300 inter">
<p class="mt-6 text-xl lg:text-lg text-gray-300">
Try before you buy. No credit card required.
</p>
<button
class="font-semibold text-md lg:text-lg text-gray-900 bg-white px-6 lg:px-7 py-4 lg:py-3 rounded-md mt-10 inter"
class="font-semibold text-md lg:text-lg text-gray-900 bg-white px-6 lg:px-7 py-4 lg:py-3 rounded-md mt-10"
data-cal-config={"{'layout':'month_view'}"}
data-cal-link="classroomio/demo"
>
@@ -7,7 +7,7 @@
<div class="flex flex-col lg:flex-row justify-between items-center py-[10%] pl-5 lg:pl-0">
<div class="w-full lg:w-2/4">
<img src="/logo-192.png" alt="classroomio logo" class="w-[10%] lg:w-[5%] mb-5 lg:mb-10" />
<p class="text-sm lg:text-md tracking-wide leading-7 lg:leading-7 text-gray-600 inter mb-5">
<p class="text-sm lg:text-md tracking-wide leading-7 lg:leading-7 text-gray-600 mb-5 mr-2">
Launch Your Online Bootcamp In Minutes
<br />
Making teaching and learning seamless for tech bootcamps
@@ -50,32 +50,32 @@
class="flex justify-between items-start flex-col lg:flex-row w-full lg:w-2/4 pr-[5%] mt-16 lg:mt-0 space-y-6 lg:space-y-0"
>
<div>
<h3 class="mb-3 lg:mb-10 text-base lg:text-md font-semibold leading-6 text-gray-900 inter">
<h3 class="mb-3 lg:mb-10 text-base lg:text-md font-semibold leading-6 text-gray-900">
Product
</h3>
<ul class="space-y-2 lg:space-y-4">
<li class="text-sm lg:text-md tracking-wide leading-6 text-gray-600 hover:text-gray-900">
<a href="#coursemanagement"> Course Management </a>
<a href="/#coursemanagement"> Course Management </a>
</li>
<li class="text-sm lg:text-md tracking-wide leading-6 text-gray-600 hover:text-gray-900">
<a href="#customization"> Customizations </a>
<a href="/#customization"> Customizations </a>
</li>
<li class="text-sm lg:text-md tracking-wide leading-6 text-gray-600 hover:text-gray-900">
<a href="#collaboration"> Forum </a>
<a href="/#collaboration"> Forum </a>
</li>
<li class="text-sm lg:text-md tracking-wide leading-6 text-gray-600 hover:text-gray-900">
<a href="#ai"> AI Lesson Planner </a>
<a href="/#ai"> AI Lesson Planner </a>
</li>
</ul>
</div>
<div>
<h3 class="mb-3 lg:mb-10 text-base lg:text-md font-semibold leading-6 text-gray-900 inter">
<h3 class="mb-3 lg:mb-10 text-base lg:text-md font-semibold leading-6 text-gray-900">
Resources
</h3>
<ul class="space-y-2 lg:space-y-4">
<li class="text-sm lg:text-md tracking-wide leading-6 text-gray-600 hover:text-gray-900">
<a target="_blank" href="https://classroomio.substack.com/"> Blog </a>
<a href="/blog"> Blog </a>
</li>
<li class="text-sm lg:text-md tracking-wide leading-6 text-gray-600 hover:text-gray-900">
<a target="_blank" href="https://classroomio.com/docs/"> Help center </a>
@@ -94,7 +94,7 @@
</div>
<div>
<h3 class="mb-3 lg:mb-10 text-base lg:text-md font-semibold leading-6 text-gray-900 inter">
<h3 class="mb-3 lg:mb-10 text-base lg:text-md font-semibold leading-6 text-gray-900">
Company
</h3>
<ul class="space-y-2 lg:space-y-4">
@@ -19,16 +19,18 @@
>
<span>Launch Your Online Bootcamp</span>
<span class="text-[#1D4EE2] relative"
>In Minutes<svg
>In Minutes
<svg
aria-hidden="true"
viewBox="0 0 418 42"
class="absolute right-[-20%] top-3/4 h-[0.58em] fill-indigo-300/70"
preserveAspectRatio="none"
><path
>
<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
>
/>
</svg>
</span>
</h1>
<p class="mx-auto mt-10 lg:mt-6 px-4 lg:p-0 text-md md:text-lg text-slate-700 lg:w-2/4">
@@ -76,7 +78,7 @@
{#if PUBLIC_ENABLE_USERS_COMPANIES}
<div class="px-[15%] mb-[10%]">
<h2 class="inter text-base lg:text-xl font-semibold text-gray-900">Used at</h2>
<h2 class="text-base lg:text-xl font-semibold text-gray-900">Used at</h2>
<div class="w-full flex flex-wrap flex-row gap-5 justify-between items-center py-[5%]">
<img src="/hero-1.svg" alt="" class="w-[30%] lg:w-[13%]" />
<img src="/hero-2.svg" alt="" class="w-[30%] lg:w-[13%]" />
@@ -4,7 +4,7 @@
import { folder, globe, team, transcription } from '$lib/emojis';
let selected = 0;
let interval = 0;
let interval: NodeJS.Timer;
const moreFeatures = [
{
@@ -12,29 +12,28 @@
title: 'Customizable Landing Page',
description:
'A minimalistic landing page template out of the box to share your courses with the world',
image: '/landing-page-builder.png',
image: '/landing-page-builder.png'
},
{
icon: team,
title: 'Team management',
description:
'Extend invitations and manage your teaching institution seamlessly through ClassroomIO.',
image: '/team-management.png',
image: '/team-management.png'
},
{
icon: transcription,
title: 'Auto Video Transcription',
description:
'AI automatically transcribes videos, making content searchable for seamless student access.',
image: '/video-transcription.png',
image: '/video-transcription.png'
},
{
icon: folder,
title: 'Downloadable Lesson PDF',
description:
'Students can download lessons automatically for offline access.',
image: '/download-pdf.png',
},
description: 'Students can download lessons automatically for offline access.',
image: '/download-pdf.png'
}
];
onMount(() => {
@@ -50,21 +49,15 @@
<section id="morefeatures" class="py-[10%] px-3 lg:px-0 bg-gray-50">
<div class="mx-0 lg:mx-[12%]">
<div class="w-full lg:w-4/5 mx-4 lg:mx-0 mb-14">
<h2
class="mt-2 text-3xl font-bold font-display tracking-tight lg:text-4xl"
>
<h2 class="mt-2 text-3xl font-bold font-display tracking-tight lg:text-4xl">
There is More...
</h2>
<p class="mt-4 text-lg inter text-gray-500 w-[94%] lg:w-4/5">
ClassroomIO is packed with useful features while we try to make it easy
to use.
<p class="mt-4 text-lg text-gray-500 w-[94%] lg:w-4/5">
ClassroomIO is packed with useful features while we try to make it easy to use.
</p>
</div>
<div
class="flex flex-col-reverse lg:flex-row gap-3 md:gap-10"
id="image-container"
>
<div class="flex flex-col-reverse lg:flex-row gap-3 md:gap-10" id="image-container">
<div
class="w-[95%] p-3 mt-5 overflow-auto lg:overflow-hidden lg:mt-0 lg:w-[45%] flex lg:block"
>
@@ -8,6 +8,7 @@
import ForumIcon from 'carbon-icons-svelte/lib/Forum.svelte';
import CourseIcon from '$lib/Icons/CourseIcon.svelte';
import MapCenter from 'carbon-icons-svelte/lib/MapCenter.svelte';
import { goto } from '$app/navigation';
let showsubNav = false;
let showNav = false;
@@ -89,7 +90,10 @@
<button
use:melt={$item}
class="flex justify-between items-center w-full rounded-lg hover:bg-slate-100 p-5 mb-4"
on:m-click={() => scroll(superpower.key)}
on:m-click={() => {
goto('/');
setTimeout(() => scroll(superpower.key), 200);
}}
>
{#if superpower.key === 'coursemanagement'}
<CourseIcon />
@@ -114,13 +118,22 @@
<div use:melt={$arrow} />
</div>
</li>
<!-- -->
<a href="#morefeatures">
<!-- More Features -->
<!-- <a href="/#morefeatures">
<li class="text-gray-800 font-semibold text-sm cursor-pointer">More features</li>
</a>
<a href="#pricing">
</a> -->
<!-- Pricing -->
<a href="/#pricing">
<li class="text-gray-800 font-semibold text-sm cursor-pointer">Pricing</li>
</a>
<!-- Docs -->
<a href="/docs">
<li class="text-gray-800 font-semibold text-sm cursor-pointer">Docs</li>
</a>
<!-- Blog -->
<a href="/blog">
<li class="text-gray-800 font-semibold text-sm cursor-pointer">Blog</li>
</a>
</ul>
</nav>
@@ -172,7 +185,7 @@
{#if showsubNav}
<div in:fly={{ y: -20, duration: 700 }} out:fly={{ y: 20, duration: 400 }}>
{#each superpowers as superpower}
<a href="#{superpower.key}">
<a href="/#{superpower.key}">
<p
class="font-normal text-xs text-gray-700 hover:bg-gray-100 rounded-lg py-2.5 pl-5"
>
@@ -183,16 +196,32 @@
</div>
{/if}
</li>
<!-- -->
<!-- Pricing -->
<li
class="text-gray-800 font-semibold text-sm md:text-lg cursor-pointer hover:bg-gray-100 py-3 px-4 rounded-md w-full"
class="text-gray-800 font-semibold text-sm md:text-lg cursor-pointer hover:bg-gray-100 py-3 px-4 rounded-xl w-full"
>
<a href="#morefeatures"> More features </a>
<a on:click={handleShowNav} href="/#pricing"> Pricing </a>
</li>
<!-- Docs -->
<li
class="text-gray-800 font-semibold text-sm md:text-lg cursor-pointer hover:bg-gray-100 py-3 px-4 rounded-md w-full"
>
<a href="#pricing"> Pricing </a>
<a on:click={handleShowNav} href="/docs"> Docs </a>
</li>
<!-- Blog -->
<li
class="text-gray-800 font-semibold text-sm md:text-lg cursor-pointer hover:bg-gray-100 py-3 px-4 rounded-md w-full"
>
<a on:click={handleShowNav} href="/blog"> Blog </a>
</li>
<!-- More Features -->
<li
class="text-gray-800 font-semibold text-sm md:text-lg cursor-pointer hover:bg-gray-100 py-3 px-4 rounded-md w-full"
>
<a on:click={handleShowNav} href="/#morefeatures"> More features </a>
</li>
</ul>
</nav>
@@ -39,11 +39,11 @@
<section id="pricing" class="py-[12%]">
<div class="px-[6%] flex flex-col justify-center items-center">
<div class="text-center mb-[3%]">
<h3 id="pricing" class="inter text-[#1D4EE2] text-md font-semibold tracking-wide">Pricing</h3>
<h3 id="pricing" class="text-[#1D4EE2] text-md font-semibold tracking-wide">Pricing</h3>
<h1 class="my-5 lg:my-4 font-semibold tracking-tight text-gray-900 text-3xl lg:text-4xl">
For teams and individuals
</h1>
<p class="inter mt-4 text-lg text-gray-500 tracking-normal lg:tracking-wide">
<p class="mt-4 text-lg text-gray-500 tracking-normal lg:tracking-wide">
Customizable LMS, AI integration for productive educators and many more...
</p>
</div>
@@ -55,12 +55,12 @@
style="background-color: {prices ? 'initial' : '#1D4EE2'}; color: {prices
? '#777E8A'
: '#fff'}"
class="bg-[#1D4EE2] text-white rounded-[30px] py-1 px-3 lg:py-2 lg:px-4 inter text-xs"
class="bg-[#1D4EE2] text-white rounded-[30px] py-1 px-3 lg:py-2 lg:px-4 text-xs"
on:click={handlePriceChange}>Monthly</button
>
<button
style="background-color: {prices ? '#1D4EE2' : ''}; color: {prices ? '#fff' : '#777E8A'}"
class="text-white rounded-[30px] py-1 lg:py-2 px-3 lg:px-4 inter text-xs"
class="text-white rounded-[30px] py-1 lg:py-2 px-3 lg:px-4 text-xs"
on:click={handlePriceChange}>Annually</button
>
<div
@@ -74,14 +74,14 @@
<!-- card 1 -->
<div class="ring-gray-200 rounded-3xl p-8 ring-1 xl:p-9 max-w-xl lg:max-w-sm">
<h3 class="text-gray-900 text-lg lg:text-xl font-semibold leading-8">Hobby</h3>
<p class="text-gray-500 font-light mt-4 text-sm lg:text-md leading-6 lg:leading-6 inter">
<p class="text-gray-500 font-light mt-4 text-sm lg:text-md leading-6 lg:leading-6">
For personal use. Hobby plan is free for up to 5 courses forever, no credit card required.
</p>
<h1 class="mt-6 flex items-baseline gap-x-1 text-4xl lg:text-4xl font-medium inter">
<h1 class="mt-6 flex items-baseline gap-x-1 text-4xl lg:text-4xl font-medium">
$0 <sub class="text-base">/mo</sub>
</h1>
<button
class="font-medium lg:font-semibold text-md lg:text-lg text-white py-3 lg:py-3 w-full bg-slate-900 hover:bg-slate-700 rounded-md lg:rounded-md mt-10 inter"
class="font-medium lg:font-semibold text-md lg:text-lg text-white py-3 lg:py-3 w-full bg-slate-900 hover:bg-slate-700 rounded-md lg:rounded-md mt-10"
data-cal-config={"{'layout':'month_view'}"}
data-cal-link="classroomio/demo"
>
@@ -104,16 +104,14 @@
<!-- card 2 -->
<div class="bg-gray-900 rounded-3xl p-8 xl:p-9 max-w-xl lg:max-w-lg">
<h3 class="text-white text-lg lg:text-xl font-semibold leading-8">Pro</h3>
<p class="text-white font-light mt-4 text-sm lg:text-md leading-6 lg:leading-6 inter">
<p class="text-white font-light mt-4 text-sm lg:text-md leading-6 lg:leading-6">
Advanced features for small teaching businesses. Built for scale.
</p>
<h1
class="mt-6 text-white flex items-baseline gap-x-1 text-4xl lg:text-4xl font-medium inter"
>
<h1 class="mt-6 text-white flex items-baseline gap-x-1 text-4xl lg:text-4xl font-medium">
${prices ? '12' : '15'} <sub class="text-base">/member</sub>
</h1>
<button
class="font-medium lg:font-semibold text-md lg:text-lg text-slate-900 py-3 lg:py-3 w-full bg-white hover:bg-indigo-50 rounded-md lg:rounded-md mt-10 inter"
class="font-medium lg:font-semibold text-md lg:text-lg text-slate-900 py-3 lg:py-3 w-full bg-white hover:bg-indigo-50 rounded-md lg:rounded-md mt-10"
data-cal-config={"{'layout':'month_view'}"}
data-cal-link="classroomio/demo"
>
@@ -132,14 +130,14 @@
<!-- card 3 -->
<div class="ring-gray-200 rounded-3xl p-8 ring-1 xl:p-9 max-w-xl lg:max-w-sm">
<h3 class="text-gray-900 text-lg lg:text-xl font-semibold leading-8">Team</h3>
<p class="text-gray-500 font-light mt-4 text-sm lg:text-md leading-6 lg:leading-6 inter">
<p class="text-gray-500 font-light mt-4 text-sm lg:text-md leading-6 lg:leading-6">
Best suited for teams and larger businesses that need more control.
</p>
<h1 class="mt-6 lg:mt-6 flex items-baseline gap-x-1 text-4xl lg:text-4xl font-medium inter">
<h1 class="mt-6 lg:mt-6 flex items-baseline gap-x-1 text-4xl lg:text-4xl font-medium">
${prices ? '42' : '50'} <sub class="text-base">/member</sub>
</h1>
<button
class="font-medium lg:font-semibold text-md lg:text-lg text-white py-3 lg:py-3 w-full bg-slate-900 hover:bg-slate-700 rounded-md lg:rounded-md mt-10 inter"
class="font-medium lg:font-semibold text-md lg:text-lg text-white py-3 lg:py-3 w-full bg-slate-900 hover:bg-slate-700 rounded-md lg:rounded-md mt-10"
data-cal-config={"{'layout':'month_view'}"}
data-cal-link="classroomio/demo"
>
@@ -171,14 +169,14 @@
Hobby
</h2>
<p
class="m-0 lg:mt-1 text-md leading-7 lg:leading-6 text-gray-600 inter"
class="m-0 lg:mt-1 text-md leading-7 lg:leading-6 text-gray-600"
>
For personal use. Hobby plan is free for up to 5 courses forever, no
credit card required.
</p>
</div>
<button
class="font-semibold text-base lg:text-md text-white leading-5 mt-5 lg:m-0 p-4 lg:py-5 ml-5 bg-[#1D4EE2] rounded-lg lg:rounded-md inter w-[70%] lg:w-full"
class="font-semibold text-base lg:text-md text-white leading-5 mt-5 lg:m-0 p-4 lg:py-5 ml-5 bg-[#1D4EE2] rounded-lg lg:rounded-md w-[70%] lg:w-full"
>
Create a free account
</button>
@@ -0,0 +1,13 @@
<script lang="ts">
export let src: string;
export let alt: string;
</script>
<figure>
<img
{src}
{alt}
loading="lazy"
class="max-w-full w-full h-[400px] object-cover my-2 rounded-lg"
/>
</figure>
@@ -0,0 +1,2 @@
import img from './img.svelte';
export { img };
+14
View File
@@ -0,0 +1,14 @@
export type Categories = 'sveltekit' | 'svelte';
export type BlogPost = {
title: string;
slug: string;
description: string;
tags: string[];
author: string;
role: string;
avatar: string;
date: string;
categories: Categories[];
published: boolean;
};
@@ -0,0 +1,8 @@
type DateStyle = Intl.DateTimeFormatOptions['dateStyle'];
export function formatDate(date: string, dateStyle: DateStyle = 'medium', locales = 'en') {
// Safari is mad about dashes in the date
const dateToFormat = new Date(date.replaceAll('-', '/'));
const dateFormatter = new Intl.DateTimeFormat(locales, { dateStyle });
return dateFormatter.format(dateToFormat);
}
+6
View File
@@ -0,0 +1,6 @@
<script lang="ts" context="module">
import { img } from '$lib/custom/index';
export { img };
</script>
<slot />
@@ -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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 324 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

+35 -11
View File
@@ -1,16 +1,40 @@
import { preprocessMeltUI } from "@melt-ui/pp";
import sequence from "svelte-sequential-preprocessor";
import adapter from "@sveltejs/adapter-auto";
import { vitePreprocess } from "@sveltejs/kit/vite";
import { preprocessMeltUI } from '@melt-ui/pp';
import sequence from 'svelte-sequential-preprocessor';
import adapter from '@sveltejs/adapter-auto';
import { vitePreprocess } from '@sveltejs/kit/vite';
import { mdsvex, escapeSvelte } from 'mdsvex';
import shiki from 'shiki';
import remarkUnwrapImages from 'remark-unwrap-images';
import remarkToc from 'remark-toc';
import rehypeSlug from 'rehype-slug';
/** @type {import('@sveltejs/kit').Config}*/
/** @type {import('mdsvex').MdsvexOptions} */
const mdsvexOptions = {
extensions: ['.md'],
layout: {
_: './src/mdsvex.svelte'
},
highlight: {
highlighter: async (code, lang = 'text') => {
const highlighter = await shiki.getHighlighter({ theme: 'poimandres' });
const html = escapeSvelte(highlighter.codeToHtml(code, { lang }));
return `{@html \`${html}\` }`;
}
},
remarkPlugins: [remarkUnwrapImages, [remarkToc, { tight: true }]],
rehypePlugins: [rehypeSlug]
};
const config = {
kit: {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter(),
},
preprocess: sequence([vitePreprocess(), preprocessMeltUI()]),
kit: {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter()
},
extensions: ['.svelte', '.md'],
preprocess: sequence([vitePreprocess(), preprocessMeltUI(), mdsvex(mdsvexOptions)])
};
export default config;
+2 -2
View File
@@ -2,7 +2,7 @@
export default {
content: ['./src/**/*.{html,js,svelte,ts}'],
theme: {
extend: {},
extend: {}
},
plugins: [],
plugins: []
};