Merge pull request #8 from MealCraft/feature/into_the_unknown
Feature/into the unknown
This commit is contained in:
commit
7b1d007ff4
8 changed files with 282 additions and 7 deletions
|
|
@ -4,7 +4,7 @@ TODO:
|
||||||
- [x] Set up new laptop github workflow
|
- [x] Set up new laptop github workflow
|
||||||
- [x] Download next js
|
- [x] Download next js
|
||||||
- [x] Aws terraform plan and apply configured
|
- [x] Aws terraform plan and apply configured
|
||||||
- [] Deploy into my new k8s
|
- [x] Deploy into my new k8s
|
||||||
- [x] k get pods -A works
|
- [x] k get pods -A works
|
||||||
- [x] deploy docker registry credentials
|
- [x] deploy docker registry credentials
|
||||||
- [x] deploy storageclass
|
- [x] deploy storageclass
|
||||||
|
|
@ -13,4 +13,8 @@ TODO:
|
||||||
- [x] deploy next js to juntekim.com
|
- [x] deploy next js to juntekim.com
|
||||||
- [x] Traefik certs change from staging to production
|
- [x] Traefik certs change from staging to production
|
||||||
- [x] Merge my code to main
|
- [x] Merge my code to main
|
||||||
- [x] Push from workflow k8s bootstrap
|
- [x] Push from workflow k8s bootstrap
|
||||||
|
- [] Add my favroutie quotes in a file and everytime someone joins it shows a new one
|
||||||
|
n8n
|
||||||
|
home assistant deploy
|
||||||
|
ajay website deploy
|
||||||
3
juntekim_frontend/app/About/page.tsx
Normal file
3
juntekim_frontend/app/About/page.tsx
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
export default function About() {
|
||||||
|
return <h1>Everything you need to know about me will be here</h1>;
|
||||||
|
}
|
||||||
42
juntekim_frontend/app/[...path]/page.tsx
Normal file
42
juntekim_frontend/app/[...path]/page.tsx
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
import fs from "fs";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
export default function FilePage({ params }: { params: { path?: string[] } }) {
|
||||||
|
const filePath = params.path?.join("/") || "";
|
||||||
|
|
||||||
|
// Resolve to actual file in public folder
|
||||||
|
const fullPath = path.join(process.cwd(), "public", filePath);
|
||||||
|
|
||||||
|
// If folder or file missing
|
||||||
|
if (!fs.existsSync(fullPath)) {
|
||||||
|
return (
|
||||||
|
<div className="p-6 font-mono text-red-400">
|
||||||
|
404 - File not found: /{filePath}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it's a folder, list its contents
|
||||||
|
if (fs.lstatSync(fullPath).isDirectory()) {
|
||||||
|
const files = fs.readdirSync(fullPath);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="p-6 font-mono text-green-400">
|
||||||
|
<h2 className="mb-4 text-xl font-bold text-zinc-200">/{filePath}</h2>
|
||||||
|
{files.map((name) => (
|
||||||
|
<div key={name}>- {name}</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read file contents
|
||||||
|
const content = fs.readFileSync(fullPath, "utf8");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="p-6 font-mono text-green-400 whitespace-pre-wrap">
|
||||||
|
<h2 className="mb-4 text-xl font-bold text-zinc-200">/{filePath}</h2>
|
||||||
|
{content}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
137
juntekim_frontend/app/components/TerminalBox.tsx
Normal file
137
juntekim_frontend/app/components/TerminalBox.tsx
Normal file
|
|
@ -0,0 +1,137 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import { QUOTES } from "@/lib/quotes";
|
||||||
|
|
||||||
|
export default function TerminalBox({ children }: { children: React.ReactNode }) {
|
||||||
|
const [showFirstPrompt, setShowFirstPrompt] = useState(false);
|
||||||
|
const [showEnterEcho, setShowEnterEcho] = useState(false);
|
||||||
|
const [typedCommand1, setTypedCommand1] = useState("");
|
||||||
|
const [showQuote, setShowQuote] = useState(false);
|
||||||
|
const [quote, setQuote] = useState("");
|
||||||
|
const [typedCommand2, setTypedCommand2] = useState("");
|
||||||
|
const [showLoader, setShowLoader] = useState(false);
|
||||||
|
const [loaderProgress, setLoaderProgress] = useState(0);
|
||||||
|
const [showTree, setShowTree] = useState(false);
|
||||||
|
|
||||||
|
// INIT
|
||||||
|
useEffect(() => {
|
||||||
|
setQuote(QUOTES[Math.floor(Math.random() * QUOTES.length)]);
|
||||||
|
|
||||||
|
setTimeout(() => setShowFirstPrompt(true), 400);
|
||||||
|
setTimeout(() => setShowEnterEcho(true), 1500);
|
||||||
|
setTimeout(() => typeCommand1(), 1800);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// TYPE COMMAND 1
|
||||||
|
const typeCommand1 = () => {
|
||||||
|
const cmd = "juntekim@site:~$ quoteOfTheDay";
|
||||||
|
let i = 0;
|
||||||
|
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
setTypedCommand1(cmd.slice(0, i + 1));
|
||||||
|
i++;
|
||||||
|
if (i >= cmd.length) {
|
||||||
|
clearInterval(interval);
|
||||||
|
|
||||||
|
setTimeout(() => setShowQuote(true), 300);
|
||||||
|
setTimeout(() => typeCommand2(), 1200);
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
};
|
||||||
|
|
||||||
|
// TYPE COMMAND 2
|
||||||
|
const typeCommand2 = () => {
|
||||||
|
const cmd = "juntekim@site:~$ tree .";
|
||||||
|
let i = 0;
|
||||||
|
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
setTypedCommand2(cmd.slice(0, i + 1));
|
||||||
|
i++;
|
||||||
|
if (i >= cmd.length) {
|
||||||
|
clearInterval(interval);
|
||||||
|
|
||||||
|
setTimeout(() => startLoader(), 400);
|
||||||
|
}
|
||||||
|
}, 60);
|
||||||
|
};
|
||||||
|
|
||||||
|
// LOADER
|
||||||
|
const startLoader = () => {
|
||||||
|
setShowLoader(true);
|
||||||
|
|
||||||
|
let progress = 0;
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
progress += Math.random() * 20;
|
||||||
|
|
||||||
|
if (progress >= 100) {
|
||||||
|
progress = 100;
|
||||||
|
clearInterval(interval);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setShowTree(true);
|
||||||
|
setShowLoader(false);
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
setLoaderProgress(Math.floor(progress));
|
||||||
|
}, 300);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Loader UI
|
||||||
|
const LoaderBar = () => (
|
||||||
|
<div className="text-green-400 font-mono mt-2">
|
||||||
|
compiling… {loaderProgress}%
|
||||||
|
<div className="w-full bg-zinc-800 h-2 rounded mt-1">
|
||||||
|
<div
|
||||||
|
className="bg-green-500 h-2 rounded"
|
||||||
|
style={{ width: `${loaderProgress}%` }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="rounded-lg border border-zinc-700 bg-black text-zinc-100 p-4 font-mono text-sm shadow-xl w-full max-w-2xl"
|
||||||
|
style={{ whiteSpace: "pre-wrap" }}
|
||||||
|
>
|
||||||
|
{/* Prompt 1 */}
|
||||||
|
{showFirstPrompt && <div className="text-green-400">juntekim@site:~$</div>}
|
||||||
|
|
||||||
|
{/* Enter echo */}
|
||||||
|
{showEnterEcho && <div className="text-green-400">juntekim@site:~$</div>}
|
||||||
|
|
||||||
|
{/* Command 1 (NO cursor here) */}
|
||||||
|
{typedCommand1 && (
|
||||||
|
<div className="text-green-400">{typedCommand1}</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Quote */}
|
||||||
|
{showQuote && (
|
||||||
|
<div className="text-zinc-300 italic my-2 animate-fadeIn">{quote}</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Command 2 (NO cursor here) */}
|
||||||
|
{typedCommand2 && (
|
||||||
|
<div className="text-green-400">{typedCommand2}</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Loader */}
|
||||||
|
{showLoader && <LoaderBar />}
|
||||||
|
|
||||||
|
{/* Final tree */}
|
||||||
|
{showTree && (
|
||||||
|
<div className="animate-fadeIn mt-2 text-green-400">
|
||||||
|
/
|
||||||
|
<div className="ml-2">{children}</div>
|
||||||
|
|
||||||
|
{/* Final Prompt WITH cursor */}
|
||||||
|
<div className="text-green-400 mt-2">
|
||||||
|
juntekim@site:~$ <span className="animate-pulse">▮</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -24,3 +24,12 @@ body {
|
||||||
color: var(--foreground);
|
color: var(--foreground);
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from { opacity: 0; transform: translateY(-2px); }
|
||||||
|
to { opacity: 1; transform: translateY(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-fadeIn {
|
||||||
|
animation: fadeIn 0.4s ease forwards;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,28 @@
|
||||||
import Image from "next/image";
|
import TerminalBox from "./components/TerminalBox";
|
||||||
|
import { getRouteTree, RouteNode } from "../lib/routeTree";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
|
const routes = getRouteTree();
|
||||||
|
|
||||||
|
function renderTree(nodes: RouteNode[], depth = 0) {
|
||||||
|
return nodes.map((node, i) => (
|
||||||
|
<div key={node.path}>
|
||||||
|
<div style={{ marginLeft: depth * 16 }}>
|
||||||
|
<a href={node.path} className="text-green-400 hover:underline">
|
||||||
|
{depth === 0 ? "├── " : "│ ".repeat(depth) + "└── "}
|
||||||
|
{node.name}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{node.children && renderTree(node.children, depth + 1)}
|
||||||
|
</div>
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-screen flex-col items-center justify-center space-y-6">
|
<div className="flex min-h-screen items-center justify-center p-10">
|
||||||
<h1 className="text-3xl font-bold text-center">
|
<TerminalBox>
|
||||||
Impatient with actions, Patient with results
|
{renderTree(routes)}
|
||||||
</h1>
|
</TerminalBox>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
7
juntekim_frontend/lib/quotes.ts
Normal file
7
juntekim_frontend/lib/quotes.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
export const QUOTES = [
|
||||||
|
'"Impatient with actions, patient with results." - Naval Ravikant',
|
||||||
|
'"What good shall I do today? - Benjamin Franklin"',
|
||||||
|
'"Nothing like a health problem to turn up the contrast dial on the rest of life." - Naval Ravikant',
|
||||||
|
'"If you want to go fast go alone; if you want to go far go together" - Unknown',
|
||||||
|
'“I don’t know if it happened for the best — but I know I’ll make the best out of whatever happens.” - Unknown',
|
||||||
|
];
|
||||||
56
juntekim_frontend/lib/routeTree.ts
Normal file
56
juntekim_frontend/lib/routeTree.ts
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
import fs from "fs";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
export type RouteNode = {
|
||||||
|
name: string;
|
||||||
|
path: string;
|
||||||
|
children?: RouteNode[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export function getRouteTree(): RouteNode[] {
|
||||||
|
const appDir = path.join(process.cwd(), "app");
|
||||||
|
|
||||||
|
function walk(currentDir: string, baseRoute = ""): RouteNode[] {
|
||||||
|
const entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
||||||
|
|
||||||
|
return entries
|
||||||
|
.filter((e) => {
|
||||||
|
if (!e.isDirectory()) return false;
|
||||||
|
|
||||||
|
// EXCLUDE folders that should not be routes
|
||||||
|
if (e.name.startsWith("_")) return false;
|
||||||
|
if (e.name.startsWith("(")) return false;
|
||||||
|
if (e.name.startsWith("[")) return false; // hide [...path]
|
||||||
|
|
||||||
|
// Only include if folder HAS a page.tsx OR contains nested route pages
|
||||||
|
const folderPath = path.join(currentDir, e.name);
|
||||||
|
const hasPage = fs.existsSync(path.join(folderPath, "page.tsx"));
|
||||||
|
|
||||||
|
const hasNestedPages = fs
|
||||||
|
.readdirSync(folderPath)
|
||||||
|
.some((child) => {
|
||||||
|
const full = path.join(folderPath, child);
|
||||||
|
return (
|
||||||
|
fs.lstatSync(full).isDirectory() &&
|
||||||
|
fs.existsSync(path.join(full, "page.tsx"))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return hasPage || hasNestedPages;
|
||||||
|
})
|
||||||
|
.map((folder) => {
|
||||||
|
const folderPath = path.join(currentDir, folder.name);
|
||||||
|
const routePath = `${baseRoute}/${folder.name}`;
|
||||||
|
|
||||||
|
const children = walk(folderPath, routePath);
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: folder.name,
|
||||||
|
path: routePath,
|
||||||
|
children,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return walk(appDir, "");
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue