added project pages, updated page for FAM.
This commit is contained in:
10
app/context/ProjectContext.tsx
Normal file
10
app/context/ProjectContext.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
'use client';
|
||||
import { createContext, useContext } from 'react';
|
||||
|
||||
const ProjectContext = createContext<any>(null);
|
||||
|
||||
export function ProjectProvider({ children, value }: { children: React.ReactNode, value: any }) {
|
||||
return <ProjectContext.Provider value={value}>{children}</ProjectContext.Provider>;
|
||||
}
|
||||
|
||||
export const useSharedData = () => useContext(ProjectContext);
|
||||
@@ -149,6 +149,14 @@ body {
|
||||
height: 28;
|
||||
}
|
||||
|
||||
.expand-on-hover-button {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.expand-on-hover-button:hover {
|
||||
scale: 1.05;
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 640px) {
|
||||
h1 {
|
||||
font-size: 32px !important;
|
||||
|
||||
@@ -5,6 +5,7 @@ import "./globals.css";
|
||||
import { ThemeProvider } from 'next-themes'
|
||||
import ThemeSwitch from "@/components/ThemeSwitch";
|
||||
|
||||
|
||||
const mono = JetBrains_Mono({
|
||||
subsets: ["latin"],
|
||||
variable: "--mono",
|
||||
|
||||
@@ -4,9 +4,7 @@ import { useState } from "react";
|
||||
import { useMountTransition } from "@/hooks/useAnimations";
|
||||
import Nav from "@/components/Nav";
|
||||
import Profile from "@/components/Profile";
|
||||
import Projects from "@/components/Projects";
|
||||
import Footer from "@/components/Footer";
|
||||
|
||||
export default function Home() {
|
||||
const [section, setSection] = useState("profile");
|
||||
const mounted = useMountTransition();
|
||||
@@ -44,11 +42,9 @@ export default function Home() {
|
||||
|
||||
</header>
|
||||
|
||||
<Nav section={section} setSection={setSection} />
|
||||
|
||||
<Nav section={"profile"} />
|
||||
<main>
|
||||
{section === "profile" && <Profile />}
|
||||
{section === "projects" && <Projects />}
|
||||
<Profile />
|
||||
</main>
|
||||
</div>
|
||||
|
||||
|
||||
54
app/profile/layout.tsx
Normal file
54
app/profile/layout.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
"use client";
|
||||
|
||||
|
||||
import Nav from "@/components/Nav";
|
||||
|
||||
import Footer from "@/components/Footer";
|
||||
export default function Layout({children}: {
|
||||
children: React.ReactNode;
|
||||
params: Promise<{ id: string }>;
|
||||
}) {
|
||||
|
||||
|
||||
return (
|
||||
<div style={{ minHeight: "100vh", paddingBottom: 36 }}>
|
||||
<div
|
||||
style={{
|
||||
maxWidth: 880,
|
||||
margin: "0 auto",
|
||||
padding: "0 24px",
|
||||
transition: "all 0.5s cubic-bezier(0.16, 1, 0.3, 1)",
|
||||
}}
|
||||
>
|
||||
<header
|
||||
style={{
|
||||
padding: "24px 0 0",
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontFamily: "var(--mono)",
|
||||
fontSize: 14,
|
||||
fontWeight: 700,
|
||||
color: "var(--accent)",
|
||||
letterSpacing: "-0.02em",
|
||||
}}
|
||||
>
|
||||
</div>
|
||||
|
||||
</header>
|
||||
|
||||
<Nav section={"profile"} />
|
||||
|
||||
<main>
|
||||
{children}
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
12
app/profile/page.tsx
Normal file
12
app/profile/page.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import Profile from "@/components/Profile";
|
||||
export default function ProfilePage() {
|
||||
return (
|
||||
|
||||
<main>
|
||||
<Profile />
|
||||
</main>
|
||||
|
||||
);
|
||||
}
|
||||
18
app/project/[slug]/layout.tsx
Normal file
18
app/project/[slug]/layout.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import { ProjectProvider } from "../../context/ProjectContext";
|
||||
import { getProjectDetails } from "@/data/content";
|
||||
|
||||
export default async function SlugLayout({children, params}: {
|
||||
children: React.ReactNode;
|
||||
params: Promise<{ slug: string }>;
|
||||
}) {
|
||||
|
||||
const {slug} = await params;
|
||||
const projectData = await getProjectDetails(slug)
|
||||
return (
|
||||
<ProjectProvider value={projectData}>
|
||||
<main>
|
||||
{children}
|
||||
</main>
|
||||
</ProjectProvider>
|
||||
);
|
||||
}
|
||||
105
app/project/[slug]/page.tsx
Normal file
105
app/project/[slug]/page.tsx
Normal file
@@ -0,0 +1,105 @@
|
||||
'use client'
|
||||
import { use } from 'react'
|
||||
|
||||
import { redirect, RedirectType } from 'next/navigation'
|
||||
import { useSharedData } from '@/app/context/ProjectContext';
|
||||
import { useMountTransition } from '@/hooks/useAnimations';
|
||||
import "../../../styles/markdown-container.css";
|
||||
import Link from 'next/link';
|
||||
import { PROJECTS } from '@/data/content';
|
||||
|
||||
export default function ProjectPage({
|
||||
params,
|
||||
}: {params: Promise<{ slug: string }>}) {
|
||||
|
||||
const mounted = useMountTransition(50)
|
||||
const { slug } = use(params);
|
||||
|
||||
if (!slug) redirect('project',RedirectType.replace);
|
||||
|
||||
const hasValidProject = PROJECTS.find((v)=>v.slug == slug)
|
||||
const hasValidDetails = hasValidProject && PROJECTS.find((v)=>v.slug == slug)?.details
|
||||
const projectDetails = useSharedData();
|
||||
|
||||
return (
|
||||
<div
|
||||
id="project-markdown-container"
|
||||
className={"markdown-container"}
|
||||
style={{
|
||||
opacity: mounted ? 1 : 0,
|
||||
transition: "all 0.5s ease",
|
||||
translate: mounted ? "0 2em" : "0 0"
|
||||
}}
|
||||
>
|
||||
|
||||
{
|
||||
hasValidDetails ?
|
||||
(
|
||||
<main dangerouslySetInnerHTML={{ __html: projectDetails }}>
|
||||
</main>
|
||||
) : (
|
||||
<p>This project has no details set up for it yet.</p>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
<div style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
gap: "1em",
|
||||
marginBottom: "2em"
|
||||
}}>
|
||||
<Link onClick={(e)=>{
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
left: 0,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}}
|
||||
|
||||
className="expand-on-hover-button"
|
||||
style={{
|
||||
fontFamily: "var(--mono)",
|
||||
fontSize: 15,
|
||||
color: "var(--fg)",
|
||||
border: "1px solid var(--border)",
|
||||
backgroundColor: "var(--bg)",
|
||||
height: "3em",
|
||||
display: "block",
|
||||
alignContent: "center",
|
||||
alignItems: "center",
|
||||
textAlign: "center",
|
||||
width: "10em",
|
||||
borderRadius: "var(--radius-md)",
|
||||
|
||||
}} href={"#"}>Back To Top</Link>
|
||||
|
||||
<Link onClick={(e)=>{
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
left: 0,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}}
|
||||
|
||||
className="expand-on-hover-button"
|
||||
style={{
|
||||
fontFamily: "var(--mono)",
|
||||
fontSize: 15,
|
||||
color: "var(--fg)",
|
||||
border: "1px solid var(--border)",
|
||||
backgroundColor: "var(--bg)",
|
||||
height: "3em",
|
||||
display: "block",
|
||||
alignContent: "center",
|
||||
alignItems: "center",
|
||||
textAlign: "center",
|
||||
width: "10em",
|
||||
borderRadius: "var(--radius-md)",
|
||||
|
||||
}} href={"/project"}>More Projects</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
55
app/project/layout.tsx
Normal file
55
app/project/layout.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
|
||||
import Nav from "@/components/Nav";
|
||||
|
||||
import Footer from "@/components/Footer";
|
||||
|
||||
export default async function Layout({children, params}: {
|
||||
children: React.ReactNode;
|
||||
params: Promise<{ slug: string }>;
|
||||
}) {
|
||||
|
||||
const {slug} = await params;
|
||||
|
||||
|
||||
return (
|
||||
<div style={{ minHeight: "100vh", paddingBottom: 36 }}>
|
||||
<div
|
||||
style={{
|
||||
maxWidth: 880,
|
||||
margin: "0 auto",
|
||||
padding: "0 24px",
|
||||
transition: "all 0.5s cubic-bezier(0.16, 1, 0.3, 1)",
|
||||
}}
|
||||
>
|
||||
<header
|
||||
style={{
|
||||
padding: "24px 0 0",
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontFamily: "var(--mono)",
|
||||
fontSize: 14,
|
||||
fontWeight: 700,
|
||||
color: "var(--accent)",
|
||||
letterSpacing: "-0.02em",
|
||||
}}
|
||||
>
|
||||
</div>
|
||||
|
||||
</header>
|
||||
|
||||
<Nav section={"project"} subtitle={slug} />
|
||||
|
||||
<main>
|
||||
{children}
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
14
app/project/page.tsx
Normal file
14
app/project/page.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
"use client";
|
||||
|
||||
import ProjectsGrid from "@/components/ProjectsGrid";
|
||||
|
||||
|
||||
export default function Project() {
|
||||
return (
|
||||
|
||||
<main>
|
||||
<ProjectsGrid />
|
||||
</main>
|
||||
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user