diff --git a/README.md b/README.md
index 62423c2..8de6550 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@ TODO:
- [x] Set up new laptop github workflow
- [x] Download next js
- [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] deploy docker registry credentials
- [x] deploy storageclass
@@ -13,4 +13,8 @@ TODO:
- [x] deploy next js to juntekim.com
- [x] Traefik certs change from staging to production
- [x] Merge my code to main
- - [x] Push from workflow k8s bootstrap
\ No newline at end of file
+ - [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
\ No newline at end of file
diff --git a/juntekim_frontend/app/About/page.tsx b/juntekim_frontend/app/About/page.tsx
new file mode 100644
index 0000000..d1db225
--- /dev/null
+++ b/juntekim_frontend/app/About/page.tsx
@@ -0,0 +1,3 @@
+export default function About() {
+ return
Everything you need to know about me will be here
;
+}
diff --git a/juntekim_frontend/app/[...path]/page.tsx b/juntekim_frontend/app/[...path]/page.tsx
new file mode 100644
index 0000000..d2702fb
--- /dev/null
+++ b/juntekim_frontend/app/[...path]/page.tsx
@@ -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 (
+
+ 404 - File not found: /{filePath}
+
+ );
+ }
+
+ // If it's a folder, list its contents
+ if (fs.lstatSync(fullPath).isDirectory()) {
+ const files = fs.readdirSync(fullPath);
+
+ return (
+
+
/{filePath}
+ {files.map((name) => (
+
- {name}
+ ))}
+
+ );
+ }
+
+ // Read file contents
+ const content = fs.readFileSync(fullPath, "utf8");
+
+ return (
+
+
/{filePath}
+ {content}
+
+ );
+}
diff --git a/juntekim_frontend/app/components/TerminalBox.tsx b/juntekim_frontend/app/components/TerminalBox.tsx
new file mode 100644
index 0000000..e8c27d5
--- /dev/null
+++ b/juntekim_frontend/app/components/TerminalBox.tsx
@@ -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 = () => (
+
+ compiling… {loaderProgress}%
+
+
+ );
+
+ return (
+
+ {/* Prompt 1 */}
+ {showFirstPrompt &&
juntekim@site:~$
}
+
+ {/* Enter echo */}
+ {showEnterEcho &&
juntekim@site:~$
}
+
+ {/* Command 1 (NO cursor here) */}
+ {typedCommand1 && (
+
{typedCommand1}
+ )}
+
+ {/* Quote */}
+ {showQuote && (
+
{quote}
+ )}
+
+ {/* Command 2 (NO cursor here) */}
+ {typedCommand2 && (
+
{typedCommand2}
+ )}
+
+ {/* Loader */}
+ {showLoader &&
}
+
+ {/* Final tree */}
+ {showTree && (
+
+ /
+
{children}
+
+ {/* Final Prompt WITH cursor */}
+
+ juntekim@site:~$ ▮
+
+
+ )}
+
+ );
+}
diff --git a/juntekim_frontend/app/globals.css b/juntekim_frontend/app/globals.css
index a2dc41e..54cf200 100644
--- a/juntekim_frontend/app/globals.css
+++ b/juntekim_frontend/app/globals.css
@@ -24,3 +24,12 @@ body {
color: var(--foreground);
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;
+}
diff --git a/juntekim_frontend/app/page.tsx b/juntekim_frontend/app/page.tsx
index 2aa5eaf..8a79bc3 100644
--- a/juntekim_frontend/app/page.tsx
+++ b/juntekim_frontend/app/page.tsx
@@ -1,11 +1,28 @@
-import Image from "next/image";
+import TerminalBox from "./components/TerminalBox";
+import { getRouteTree, RouteNode } from "../lib/routeTree";
export default function Home() {
+ const routes = getRouteTree();
+
+ function renderTree(nodes: RouteNode[], depth = 0) {
+ return nodes.map((node, i) => (
+
+
+ {node.children && renderTree(node.children, depth + 1)}
+
+ ));
+ }
+
return (
-
-
- Impatient with actions, Patient with results
-
+
+
+ {renderTree(routes)}
+
);
}
diff --git a/juntekim_frontend/lib/quotes.ts b/juntekim_frontend/lib/quotes.ts
new file mode 100644
index 0000000..6696b13
--- /dev/null
+++ b/juntekim_frontend/lib/quotes.ts
@@ -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',
+];
diff --git a/juntekim_frontend/lib/routeTree.ts b/juntekim_frontend/lib/routeTree.ts
new file mode 100644
index 0000000..ad07c1e
--- /dev/null
+++ b/juntekim_frontend/lib/routeTree.ts
@@ -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, "");
+}