Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code snippets #244

Merged
merged 34 commits into from
Aug 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
3d76aef
Categories
Bashamega Aug 2, 2024
24eb99c
Categories
Bashamega Aug 2, 2024
34a0618
Tool page
Bashamega Aug 4, 2024
c406595
New Tool
Bashamega Aug 5, 2024
14cb295
Removed Icons
Bashamega Aug 5, 2024
896806d
Categories
Bashamega Aug 5, 2024
704ac0e
Hyperlink
Bashamega Aug 6, 2024
6b50171
Dynamic routing
Bashamega Aug 6, 2024
32254f1
chore: make sure the category exists
Bashamega Aug 6, 2024
e41516d
Removed categories
Bashamega Aug 6, 2024
2f19663
Removed old route
Bashamega Aug 6, 2024
707dabd
Merge https://github.com/Bashamega/WebDevTools into code-snippets
Bashamega Aug 8, 2024
dde4be4
Fromat
Bashamega Aug 8, 2024
a682db8
chore: fix spelling
Bashamega Aug 8, 2024
843982b
Language router Router
Bashamega Aug 8, 2024
29ed72f
Fetch category
Bashamega Aug 8, 2024
8c5373a
Format
Bashamega Aug 8, 2024
1fe700a
Switch to fs
Bashamega Aug 8, 2024
998bca2
Content fetch
Bashamega Aug 8, 2024
a3a05c0
Format fix
Bashamega Aug 8, 2024
e2b1424
Card1
Bashamega Aug 9, 2024
c2e8475
Delete posts
Bashamega Aug 9, 2024
036d0f9
feat: blog cards
Bashamega Aug 9, 2024
a0d92ba
Merge https://github.com/Bashamega/WebDevTools into code-snippets
Bashamega Aug 9, 2024
35b5c07
Format 🔥
Bashamega Aug 9, 2024
f4cb183
Merge https://github.com/Bashamega/WebDevTools into code-snippets
Bashamega Aug 9, 2024
cf5a06d
feat: Link
Bashamega Aug 9, 2024
8414c39
Blog page
Bashamega Aug 9, 2024
c321caa
Remove gh link
Bashamega Aug 9, 2024
da75740
Sidebar
Bashamega Aug 9, 2024
95c52b6
Blog fixes
Bashamega Aug 9, 2024
7a76bde
Update
Bashamega Aug 9, 2024
d73c8c1
fix
Bashamega Aug 9, 2024
581cb5f
API fix
Bashamega Aug 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions src/app/api/cs/[language]/doc/[title]/route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { NextResponse } from "next/server";
import languages from "@/db/codesnippets/categories.json";
import { promises as fs } from "fs";
import path from "path";

export async function GET(request, { params }) {
const { language, title } = params; // Extract language from params
const encodedLanguage = encodeURIComponent(language.toLowerCase());

// Check if the language exists in the languages list
const languageExists = languages.languages.some((lang) => {
return encodeURIComponent(lang.name.toLowerCase()) === encodedLanguage;
});

// If the language does not exist, return a 404 response
if (!languageExists) {
const response = NextResponse.json(
{ error: "Language not found" },
{ status: 404 },
);
response.headers.set("Cache-Control", "public, max-age=3600"); // Cache for 1 hour
return response;
} else {
try {
const filePath = path.join(
process.cwd(),
"/src/db/codesnippets/posts",
language.toLowerCase(),
`${title}.md`,
);
const content = await fs.readFile(filePath, "utf-8");

// If the language exists, return a success response
const response = NextResponse.json(
{ category: language, content: content },
{ status: 200 },
);
response.headers.set("Cache-Control", "public, max-age=3600"); // Cache for 1 hour
return response;
} catch (error) {
console.error(`Error loading content for language: ${language}`, error);
const response = NextResponse.json(
{ error: "Internal Server Error", message: error.message },
{ status: 500 },
);
return response;
}
}
}
47 changes: 47 additions & 0 deletions src/app/api/cs/[language]/route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { NextResponse } from "next/server";
import languages from "@/db/codesnippets/categories.json";
import { promises as fs } from "fs";
import path from "path";

export async function GET(request, { params }) {
const { language } = params; // Extract language from params
const encodedLanguage = encodeURIComponent(language.toLowerCase());

// Check if the language exists in the languages list
const languageExists = languages.languages.some((lang) => {
return encodeURIComponent(lang.name.toLowerCase()) === encodedLanguage;
});

// If the language does not exist, return a 404 response
if (!languageExists) {
const response = NextResponse.json({ error: "Not found" }, { status: 404 });
response.headers.set("Cache-Control", "public, max-age=3600"); // Cache for 1 hour
return response;
} else {
try {
const filePath = path.join(
process.cwd(),
"/src/db/codesnippets/posts",
language,
"content.json",
);
const content = await fs.readFile(filePath, "utf-8");
const parsedContent = JSON.parse(content);

// If the language exists, return a success response
const response = NextResponse.json(
{ category: language, content: parsedContent },
{ status: 200 },
);
response.headers.set("Cache-Control", "public, max-age=3600"); // Cache for 1 hour
return response;
} catch (error) {
console.error(`Error loading content for language: ${language}`, error);
const response = NextResponse.json(
{ error: "Internal Server Error", message: error.message },
{ status: 500 },
);
return response;
}
}
}
8 changes: 8 additions & 0 deletions src/app/api/cs/route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import categories from "@/db/codesnippets/categories.json";
import { NextResponse } from "next/server";

export async function GET(req) {
const response = NextResponse.json(categories, { status: 200 });
response.headers.set("Cache-Control", "public, max-age=3600"); // Cache for 1 hour
return response;
}
79 changes: 79 additions & 0 deletions src/app/cs/[language]/[article]/page.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
"use client";
import { useState, useEffect } from "react";
import { NavBar } from "@/app/components/navbar";
import languages from "@/db/codesnippets/categories.json";
import NotFound from "@/app/not-found";
import { Sidebar } from "../../components/siodebar";
import { BlogContent } from "../../components/blogContent";

export default function CodingSnippets({ params }) {
const [isDarkMode, setIsDarkMode] = useState(false);
const [articleExists, setArticleExists] = useState(true);
const [data, setData] = useState();
// Toggle theme and save preference in localStorage
const toggleTheme = () => {
const newTheme = !isDarkMode;
setIsDarkMode(newTheme);
localStorage.setItem("theme", JSON.stringify(newTheme));
};

useEffect(() => {
const storedTheme = JSON.parse(localStorage.getItem("theme"));
if (storedTheme !== null) {
setIsDarkMode(storedTheme);
}
}, []);
const title = (text) => {
return decodeURIComponent(text)
.toLowerCase()
.replace(/\b\w/g, (char) => char.toUpperCase());
};

useEffect(() => {
const languageExists = languages.languages.some((language) => {
return language.name.toLowerCase() === params.language.toLowerCase();
});
if (languageExists) {
const data = require(
`@/db/codesnippets/posts/${params.language.toLowerCase()}/content.json`,
);
const article = data.some((article) => {
return title(article.title) === title(params.article);
});
setArticleExists(article);
data.map((art) => {
if (title(art.title) === title(params.article)) {
setData(art);
}
});
} else {
setArticleExists(false);
}
}, [languages.languages, params.language, params.article]);
return (
<>
{articleExists ? (
<main
className={`h-screen overflow-auto ${isDarkMode ? "bg-gray-900 text-white" : "bg-white text-black"}`}
>
<NavBar
title={`Coding Snippets / ${title(params.language)} / ${title(params.article)}`}
isDarkMode={isDarkMode}
toggleTheme={toggleTheme}
/>
<section className="h-[calc(100vh-70px)] w-full lg:grid lg:grid-cols-[2fr_1fr] lg:gap-6">
<BlogContent
title={title(data?.title)}
doc={data?.doc}
language={params.language}
isDarkMode={isDarkMode}
/>
<Sidebar darkmode={isDarkMode} author={data?.author} />
</section>
</main>
) : (
<NotFound />
)}
</>
);
}
118 changes: 118 additions & 0 deletions src/app/cs/[language]/page.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
"use client";
import { useState, useEffect } from "react";
import { NavBar } from "../../components/navbar";
import languages from "@/db/codesnippets/categories.json";
import NotFound from "@/app/not-found";
import Link from "next/link";
import { BlogCard } from "../components/blogCard";

export default function CodingSnippetsTopic({ params }) {
const [isDarkMode, setIsDarkMode] = useState(false);
const [notfound, setNotfound] = useState(false);
const [content, setContent] = useState();

// Toggle theme and save preference in localStorage
const toggleTheme = () => {
const newTheme = !isDarkMode;
setIsDarkMode(newTheme);
localStorage.setItem("theme", JSON.stringify(newTheme));
};

useEffect(() => {
const storedTheme = JSON.parse(localStorage.getItem("theme"));
if (storedTheme !== null) {
setIsDarkMode(storedTheme);
}
}, []);

useEffect(() => {
const languageExists = languages.languages.some((language) => {
return language.name.toLowerCase() === params.language.toLowerCase();
});
if (languageExists) {
setContent(
require(
`@/db/codesnippets/posts/${params.language.toLowerCase()}/content.json`,
),
);
} else {
setNotfound(true);
}
}, [languages.languages, params.language]);

const title = (text) => {
return text.toLowerCase().replace(/\b\w/g, (char) => char.toUpperCase());
};

return (
<>
{notfound ? (
<NotFound />
) : (
<main
className={`h-screen overflow-auto ${isDarkMode ? "bg-gray-900 text-white" : "bg-white text-black"}`}
>
<NavBar
title={"Coding Snippets / " + title(params.language)}
isDarkMode={isDarkMode}
toggleTheme={toggleTheme}
/>
<div className="flex flex-col justify-center items-center h-fullpt-52 px-5">
<section className="text-center p-10 rounded-lg">
<h1 className="text-4xl font-bold mb-4">
{title(params.language)} Snippets
</h1>
<p className="text-lg">
A free collection of {title(params.language)} snippets
</p>
<section>
{content && content.length > 0 ? (
<div className="container mx-auto p-4">
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
{content.map((article, index) => (
<BlogCard
key={index}
data={article}
darkmode={isDarkMode}
/>
))}
</div>
</div>
) : (
<div>
<p>No available posts</p>
<Link
href="https://github.com/Bashamega/WebDevTools"
className="w-full sm:w-auto bg-gray-800 hover:bg-gray-700 focus:ring-4 focus:outline-none focus:ring-gray-300 text-white rounded-lg inline-flex items-center justify-center px-4 py-2.5 dark:bg-gray-700 dark:hover:bg-gray-600 dark:focus:ring-gray-700 hover:shadow-card-shadow transition-all duration-500 ease-in"
>
<svg
className="mr-3 w-7 h-7"
viewBox="0 0 1024 1024"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M8 0C3.58 0 0 3.58 0 8C0 11.54 2.29 14.53 5.47 15.59C5.87 15.66 6.02 15.42 6.02 15.21C6.02 15.02 6.01 14.39 6.01 13.72C4 14.09 3.48 13.23 3.32 12.78C3.23 12.55 2.84 11.84 2.5 11.65C2.22 11.5 1.82 11.13 2.49 11.12C3.12 11.11 3.57 11.7 3.72 11.94C4.44 13.15 5.59 12.81 6.05 12.6C6.12 12.08 6.33 11.73 6.56 11.53C4.78 11.33 2.92 10.64 2.92 7.58C2.92 6.71 3.23 5.99 3.74 5.43C3.66 5.23 3.38 4.41 3.82 3.31C3.82 3.31 4.49 3.1 6.02 4.13C6.66 3.95 7.34 3.86 8.02 3.86C8.7 3.86 9.38 3.95 10.02 4.13C11.55 3.09 12.22 3.31 12.22 3.31C12.66 4.41 12.38 5.23 12.3 5.43C12.81 5.99 13.12 6.7 13.12 7.58C13.12 10.65 11.25 11.33 9.47 11.53C9.76 11.78 10.01 12.26 10.01 13.01C10.01 14.08 10 14.94 10 15.21C10 15.42 10.15 15.67 10.55 15.59C13.71 14.53 16 11.53 16 8C16 3.58 12.42 0 8 0Z"
transform="scale(64)"
fill="#fff"
/>
</svg>

<div className="text-left">
<div className="-mt-1 font-sans text-sm font-semibold">
Add code snippets
</div>
</div>
</Link>
</div>
)}
</section>
</section>
</div>
</main>
)}
</>
);
}
39 changes: 39 additions & 0 deletions src/app/cs/components/blogCard.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from "react";
import Link from "next/link";
import { FaGithub } from "react-icons/fa";

export function BlogCard({ data, darkmode }) {
return (
<Link
href={`${window.location.href}/${data.title}`}
className={`block shadow-lg rounded-lg p-6 mb-6 transition-transform transform hover:scale-105 ${
darkmode ? "bg-gray-800 text-white" : "bg-white text-gray-800"
}`}
>
<article>
<h1 className="text-2xl font-bold mb-4 line-clamp-2">{data.title}</h1>
<div
className={`p-4 rounded-lg ${darkmode ? "bg-gray-700" : "bg-gray-100"}`}
>
<h2 className="text-2xl font-semibold">About the author</h2>
<h3 className="text-lg font-semibold">{data?.author?.name}</h3>
<p className="line-clamp-3">{data?.author?.about}</p>
{data?.author?.githubLink && (
<a
href={data?.author?.githubLink}
target="_blank"
rel="noopener noreferrer"
className={`flex items-center justify-center w-full border rounded mt-2 p-2 ${
darkmode
? "text-blue-300 hover:text-blue-500 border-blue-300 hover:border-blue-500"
: "text-blue-500 hover:text-blue-700 border-blue-500 hover:border-blue-700"
}`}
>
<FaGithub className="mr-2" /> GitHub
</a>
)}
</div>
</article>
</Link>
);
}
Loading
Loading