Update content documentation and implement basic learn page

This commit is contained in:
adilallo
2025-09-13 16:31:50 -06:00
parent 56a42db2da
commit 102a10457a
9 changed files with 173 additions and 143 deletions
+4
View File
@@ -93,6 +93,9 @@ export default async function BlogPostPage({ params }) {
// Get related articles with improved algorithm
const allPosts = getAllPosts();
// Create slug order for consistent background cycling
const slugOrder = allPosts.map((post) => post.slug);
// Simple related articles algorithm based on content similarity
const getRelatedArticles = (currentPost, allPosts, limit = 3) => {
const otherPosts = allPosts.filter((p) => p.slug !== currentPost.slug);
@@ -265,6 +268,7 @@ export default async function BlogPostPage({ params }) {
<RelatedArticles
relatedPosts={relatedArticles}
currentPostSlug={post.slug}
slugOrder={slugOrder}
/>
{/* Ask Organizer Section */}
-2
View File
@@ -1,5 +1,4 @@
import { getAllBlogPosts } from "../../lib/content";
import Header from "../components/Header";
import ContentThumbnailTemplate from "../components/ContentThumbnailTemplate";
import ContentContainer from "../components/ContentContainer";
@@ -31,7 +30,6 @@ export default function BlogPage() {
return (
<div className="min-h-screen bg-[#F4F3F1]">
<Header />
<main className="pt-16">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<div className="text-center mb-12">
+12 -14
View File
@@ -13,9 +13,10 @@ const ContentThumbnailTemplate = ({
post,
className = "",
variant = "vertical", // Internal prop for testing/development
slugOrder = [], // Array of slugs for consistent icon cycling
}) => {
// Post-specific background selection - different SVG for each post
const getBackgroundImage = (slug, variant) => {
const getBackgroundImage = (slug, variant, slugOrder) => {
const verticalImages = [
getAssetPath(ASSETS.VERTICAL_1),
getAssetPath(ASSETS.VERTICAL_2),
@@ -28,23 +29,20 @@ const ContentThumbnailTemplate = ({
getAssetPath(ASSETS.HORIZONTAL_3),
];
const images = variant === "vertical" ? verticalImages : horizontalImages;
if (!slug)
return variant === "vertical" ? verticalImages[0] : horizontalImages[0];
if (!slug) return images[0];
// Simple cycling approach to ensure different styles
const slugOrder = [
"building-community-trust",
"operational-security-mutual-aid",
"making-decisions-without-hierarchy",
"resolving-active-conflicts",
];
// Use the passed slugOrder for consistent cycling through background variants
const index = slugOrder.indexOf(slug);
const finalIndex = index >= 0 ? index % images.length : 0;
return images[finalIndex];
const backgroundIndex = index >= 0 ? index % 3 : 0; // Cycle through 3 background variants
// Return the same background index for both vertical and horizontal variants
return variant === "vertical"
? verticalImages[backgroundIndex]
: horizontalImages[backgroundIndex];
};
const backgroundImage = getBackgroundImage(post.slug, variant);
const backgroundImage = getBackgroundImage(post.slug, variant, slugOrder);
if (variant === "vertical") {
return (
+1 -1
View File
@@ -9,7 +9,7 @@ import { getAssetPath, ASSETS } from "../../lib/assetUtils";
// Configuration data for testing
export const navigationItems = [
{ href: "#", text: "Use cases", extraPadding: true },
{ href: "#", text: "Learn" },
{ href: "/learn", text: "Learn" },
{ href: "#", text: "About" },
];
+5 -5
View File
@@ -29,7 +29,7 @@ export default function HomeHeader() {
const navigationItems = [
{ href: "#", text: "Use cases", extraPadding: true },
{ href: "#", text: "Learn" },
{ href: "/learn", text: "Learn" },
{ href: "#", text: "About" },
];
@@ -79,10 +79,10 @@ export default function HomeHeader() {
? size === "home" || size === "homeMd"
? "homeMd"
: size === "large"
? "large"
: size === "homeXlarge"
? "homeXlarge"
: "xsmallUseCases"
? "large"
: size === "homeXlarge"
? "homeXlarge"
: "xsmallUseCases"
: size
}
variant={
+10 -5
View File
@@ -3,10 +3,14 @@
import { useState, useEffect } from "react";
import ContentThumbnailTemplate from "./ContentThumbnailTemplate";
export default function RelatedArticles({ relatedPosts, currentPostSlug }) {
export default function RelatedArticles({
relatedPosts,
currentPostSlug,
slugOrder = [],
}) {
// Filter out the current post from related posts
const filteredPosts = relatedPosts.filter(
(post) => post.slug !== currentPostSlug,
(post) => post.slug !== currentPostSlug
);
const [currentIndex, setCurrentIndex] = useState(0);
@@ -93,7 +97,7 @@ export default function RelatedArticles({ relatedPosts, currentPostSlug }) {
const handleMouseUp = () => {
document.removeEventListener(
"mousemove",
handleMouseMove,
handleMouseMove
);
document.removeEventListener("mouseup", handleMouseUp);
};
@@ -112,6 +116,7 @@ export default function RelatedArticles({ relatedPosts, currentPostSlug }) {
<ContentThumbnailTemplate
post={relatedPost}
variant="vertical"
slugOrder={slugOrder}
/>
</div>
))}
@@ -133,8 +138,8 @@ export default function RelatedArticles({ relatedPosts, currentPostSlug }) {
index === currentIndex
? `${progress}%`
: index < currentIndex
? "100%"
: "0%",
? "100%"
: "0%",
}}
/>
</div>
+116
View File
@@ -0,0 +1,116 @@
import ContentThumbnailTemplate from "../components/ContentThumbnailTemplate";
// Mock blog post data for testing
const mockPost1 = {
slug: "resolving-active-conflicts",
frontmatter: {
title: "Resolving Active Conflicts",
description:
"Practical steps for resolving conflicts while maintaining trust, cooperation, and shared goals",
author: "Author name",
date: "2025-04-15",
},
};
const mockPost2 = {
slug: "operational-security-mutual-aid",
frontmatter: {
title: "Operational Security for Mutual Aid",
description:
"Tactics to protect members, secure communication, and prevent Infiltration",
author: "Author name",
date: "2025-04-10",
},
};
const mockPost3 = {
slug: "making-decisions-without-hierarchy",
frontmatter: {
title: "Making decisions without hierarchy",
description:
"A brief guide to collaborative nonhierarchical decision making",
author: "Author name",
date: "2025-04-05",
},
};
export default function LearnPage() {
// Mock slug order for consistent background cycling
const mockSlugOrder = [
"resolving-active-conflicts",
"operational-security-mutual-aid",
"making-decisions-without-hierarchy",
];
return (
<div className="min-h-screen bg-[#F4F3F1]">
<div className="max-w-6xl mx-auto p-8 pt-24">
<h1 className="text-3xl font-bold text-[var(--color-content-default-primary)] mb-8">
Learn
</h1>
<div className="space-y-12">
{/* Featured Articles */}
<section>
<h2 className="text-2xl font-semibold text-[var(--color-content-default-primary)] mb-6">
Featured Articles
</h2>
<div className="flex flex-wrap gap-6">
<ContentThumbnailTemplate
post={mockPost1}
className="mb-4"
slugOrder={mockSlugOrder}
/>
<ContentThumbnailTemplate
post={mockPost2}
className="mb-4"
slugOrder={mockSlugOrder}
/>
<ContentThumbnailTemplate
post={mockPost3}
className="mb-4"
slugOrder={mockSlugOrder}
/>
</div>
</section>
{/* More Articles */}
<section>
<h2 className="text-2xl font-semibold text-[var(--color-content-default-primary)] mb-6">
More Articles
</h2>
<div className="space-y-4">
<ContentThumbnailTemplate
post={mockPost1}
variant="horizontal"
slugOrder={mockSlugOrder}
/>
<ContentThumbnailTemplate
post={mockPost2}
variant="horizontal"
slugOrder={mockSlugOrder}
/>
<ContentThumbnailTemplate
post={mockPost3}
variant="horizontal"
slugOrder={mockSlugOrder}
/>
</div>
</section>
{/* Coming Soon */}
<section className="bg-white p-6 rounded-lg shadow">
<h2 className="text-xl font-semibold text-[var(--color-content-default-primary)] mb-4">
More Content Coming Soon
</h2>
<p className="text-[var(--color-content-default-secondary)]">
We're working on adding more educational content to help you build
better communities. Check back soon for new articles and
resources.
</p>
</section>
</div>
</div>
</div>
);
}
-116
View File
@@ -1,116 +0,0 @@
import ContentThumbnailTemplate from "../components/ContentThumbnailTemplate";
// Mock blog post data for testing
const mockPost1 = {
slug: "resolving-active-conflicts",
frontmatter: {
title: "Resolving Active Conflicts",
description:
"Practical steps for resolving conflicts while maintaining trust, cooperation, and shared goals",
author: "Author name",
date: "2025-04-15",
},
};
const mockPost2 = {
slug: "operational-security-mutual-aid",
frontmatter: {
title: "Operational Security for Mutual Aid",
description:
"Tactics to protect members, secure communication, and prevent Infiltration",
author: "Author name",
date: "2025-04-10",
},
};
const mockPost3 = {
slug: "making-decisions-without-hierarchy",
frontmatter: {
title: "Making decisions without hierarchy",
description:
"A brief guide to collaborative nonhierarchical decision making",
author: "Author name",
date: "2025-04-05",
},
};
export default function TestThumbnailPage() {
return (
<div className="min-h-screen bg-gray-50 p-8">
<div className="max-w-6xl mx-auto">
<h1 className="text-3xl font-bold text-gray-900 mb-8">
ContentThumbnailTemplate Test
</h1>
<div className="space-y-12">
{/* Vertical Variant */}
<section>
<h2 className="text-2xl font-semibold text-gray-800 mb-6">
Vertical Variant
</h2>
<div className="flex flex-wrap gap-6">
<ContentThumbnailTemplate post={mockPost1} className="mb-4" />
<ContentThumbnailTemplate post={mockPost2} className="mb-4" />
<ContentThumbnailTemplate post={mockPost3} className="mb-4" />
</div>
</section>
{/* Horizontal Variant */}
<section>
<h2 className="text-2xl font-semibold text-gray-800 mb-6">
Horizontal Variant
</h2>
<div className="space-y-4">
<ContentThumbnailTemplate post={mockPost1} variant="horizontal" />
<ContentThumbnailTemplate post={mockPost2} variant="horizontal" />
<ContentThumbnailTemplate post={mockPost3} variant="horizontal" />
</div>
</section>
{/* Component Props */}
<section className="bg-white p-6 rounded-lg shadow">
<h2 className="text-xl font-semibold text-gray-800 mb-4">
Component Props
</h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 text-sm">
<div>
<h3 className="font-medium text-gray-700 mb-2">
Required Props:
</h3>
<ul className="space-y-1 text-gray-600">
<li>
<code>post</code> - Blog post object with frontmatter
</li>
</ul>
</div>
<div>
<h3 className="font-medium text-gray-700 mb-2">
Optional Props:
</h3>
<ul className="space-y-1 text-gray-600">
<li>
<code>className</code> - Additional CSS classes
</li>
<li>
<code>variant</code> - &quot;vertical&quot; (default) or
&quot;horizontal&quot; (for development/testing)
</li>
</ul>
</div>
</div>
</section>
{/* Mock Data */}
<section className="bg-white p-6 rounded-lg shadow">
<h2 className="text-xl font-semibold text-gray-800 mb-4">
Mock Data Structure
</h2>
<pre className="bg-gray-100 p-4 rounded text-sm overflow-x-auto">
{JSON.stringify(mockPost1, null, 2)}
</pre>
</section>
</div>
</div>
</div>
);
}
+25
View File
@@ -2,6 +2,31 @@
A simple guide for creating blog content for Community Rule.
## How to Upload an Article
Here's how to contribute a new article:
1. **Fork the repository** (if you haven't already)
2. **Create a new branch** for your article: `git checkout -b add-my-article-title`
3. **Create your article file** in the `content/blog/` directory
4. **Test locally** (optional but recommended):
- Run `npm install` to install dependencies
- Run `npm run dev` to start the development server
- Visit `http://localhost:3000/blog/your-article-slug` to preview
5. **Commit your changes**:
```bash
git add content/blog/your-article.md
git commit -m "Add article: Your Article Title"
```
6. **Push to your fork**:
```bash
git push origin add-my-article-title
```
7. **Create a pull request** in Gitea with:
- Clear title describing your article
- Brief description of what the article covers
- Any relevant context or notes for reviewers
## Quick Start
1. **Copy the template**: Use `content/blog/_template.md` as your starting point