Skip to content

Commit

Permalink
refactor: move under src folder
Browse files Browse the repository at this point in the history
  • Loading branch information
mahdikhashan committed Jan 21, 2023
1 parent 8f8f92b commit 17b1ec1
Show file tree
Hide file tree
Showing 23 changed files with 282 additions and 166 deletions.
35 changes: 0 additions & 35 deletions pages/_app.tsx

This file was deleted.

96 changes: 0 additions & 96 deletions pages/index.tsx

This file was deleted.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
32 changes: 32 additions & 0 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useEffect, useState } from "react";
import { ThemeProvider } from "next-themes";

import "@/styles/globals.css";
import RootLayout from "@/ui/layouts/Default";
import type { AppProps } from "next/app";

import ErrorBoundary from "@/ui/ErrorBoundary";

export default function App({ Component, pageProps }: AppProps) {
const [showing, setShowing] = useState(false);

useEffect(() => {
setShowing(true);
}, []);

if (!showing) {
return null;
}

if (typeof window === "undefined") {
return <></>;
} else {
return (
<RootLayout>
<ThemeProvider enableSystem={true} attribute="class">
<Component {...pageProps} />
</ThemeProvider>
</RootLayout>
);
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
105 changes: 105 additions & 0 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// TODO: fix forced left-margin

import Head from "next/head";
import Link from "next/link";

import { getCategories, getPostsData } from "@/lib/api";
import { InferGetStaticPropsType } from "next";

import Info from "@/ui/Info";
import Container from "@/ui/Container";
import { Suspense, useState, useEffect } from "react";
import { useTheme } from "next-themes";
import clsx from "clsx";


export default function HomePage({
posts,
projects,
}: InferGetStaticPropsType<typeof getStaticProps>) {
const [mounted, setMounted] = useState(false);
const { resolvedTheme, setTheme } = useTheme();

// After mounting, we have access to the theme
useEffect(() => setMounted(true), []);

return (
<>
<Container>
<div className="space-y-6">
<div className="space-y-8 text-white">
<div className="mt-12 max-w-screen-md space-y-4 dark:bg-red-200">
<Info />
</div>

<div className="mt-22 max-w-screen-md space-y-4">
<h1 className="md:text-2xl font-semibold text-orange-500">
Recent Blog Posts
</h1>
<Suspense fallback={null}>
<div className="flex flex-col divide-y-[1px] divide-zinc-700">
{posts.map((post: any) => (
<Link
key={post.slug}
href={{
pathname: "/blog/[slug]",
query: { slug: post.slug },
}}
className="flex flex-row py-4 justify-between hover:text-orange-500"
>
<div>{post.title}</div>
<div className="text-zinc-500">
{post.categories.map((category: any) => category.name)}
</div>
</Link>
))}
{!posts.length && <div>No Blog Posts found.</div>}
</div>
</Suspense>
</div>

<div className="mt-22 max-w-screen-md space-y-4">
<h1 className="md:text-2xl font-semibold text-orange-500">
Featured Projects
</h1>
<Suspense fallback={null}>
<div className="flex-col space-y-2">
{projects.map((project: any) => (
<Link
href={`/`}
key={project}
className="block space-y-1.5 rounded-lg border border-white/10 px-4 py-3 hover:border-white/20 bg-zinc-800"
>
<div>{project.name}</div>
<div className="line-clamp-3 text-sm text-zinc-400">
{project.slug}
</div>
</Link>
))}
{!projects.length && <div>No Project found.</div>}
</div>
</Suspense>
</div>
</div>
</div>
</Container>
</>
);
}

export async function getStaticProps() {
const butterToken = process.env.NEXT_PUBLIC_BUTTER_CMS_API_KEY;

if (butterToken) {
try {
const blogPosts = (await getPostsData()).posts;
const projects = await getCategories();

return { props: { posts: blogPosts, projects } };
} catch (e) {
// throw new Error("Could not get posts!");
}
}

return { props: { posts: [], projects: [] } };
}
File renamed without changes.
93 changes: 93 additions & 0 deletions src/ui/Container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import Head from "next/head";
import { useRouter } from "next/router";
import { useState, useEffect } from "react";
import { useTheme } from "next-themes";
// import NextLink from "next/link";
// import clsx from "clsx";

type ContainerProps = {
children: React.ReactNode;
customMeta?: {
date?: any;
};
};

export default function Container({ children, customMeta }: ContainerProps) {
const [mounted, setMounted] = useState(false);
const { resolvedTheme, setTheme } = useTheme();

// After mounting, we have access to the theme
useEffect(() => setMounted(true), []);

const router = useRouter();
const meta = {
title: "Mohi Khashan | Front-end Engineer.",
description: `Front-end developer, JavaScript enthusiast, and course creator.`,
image: "https://leerob.io/static/images/lee-banner.png",
type: "website",
...customMeta,
};

return (
<div className="bg-gray-50 dark:bg-gray-900">
<Head>
<title>{meta.title}</title>
<meta name="robots" content="follow, index" />
<meta content={meta.description} name="description" />
<meta property="og:url" content={`https://leerob.io${router.asPath}`} />
<link rel="canonical" href={`https://leerob.io${router.asPath}`} />
<meta property="og:type" content={meta.type} />
<meta property="og:site_name" content="Mohi Khashan" />
<meta property="og:description" content={meta.description} />
<meta property="og:title" content={meta.title} />
<meta property="og:image" content={meta.image} />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@leeerob" />
<meta name="twitter:title" content={meta.title} />
<meta name="twitter:description" content={meta.description} />
<meta name="twitter:image" content={meta.image} />
{meta.date && (
<meta property="article:published_time" content={meta.date} />
)}
</Head>
<button
aria-label="Toggle Dark Mode"
type="button"
className="w-9 h-9 bg-gray-200 rounded-lg dark:bg-gray-600 flex items-center justify-center hover:ring-2 ring-gray-300 transition-all"
onClick={() => setTheme(resolvedTheme === "dark" ? "light" : "dark")}
>
{mounted && (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
className="w-5 h-5 text-gray-800 dark:text-gray-200"
>
{resolvedTheme === "dark" ? (
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"
/>
) : (
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"
/>
)}
</svg>
)}
</button>
<main
id="skip"
className="flex flex-col justify-center px-8 bg-gray-50 dark:bg-gray-900"
>
{children}
</main>
</div>
);
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 17b1ec1

Please sign in to comment.